/**
 * 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.Jobs;
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.CloudJob;
import com.microsoft.azure.batch.protocol.models.DisableJobOption;
import com.microsoft.azure.batch.protocol.models.JobAddHeaders;
import com.microsoft.azure.batch.protocol.models.JobAddOptions;
import com.microsoft.azure.batch.protocol.models.JobAddParameter;
import com.microsoft.azure.batch.protocol.models.JobDeleteHeaders;
import com.microsoft.azure.batch.protocol.models.JobDeleteOptions;
import com.microsoft.azure.batch.protocol.models.JobDisableHeaders;
import com.microsoft.azure.batch.protocol.models.JobDisableOptions;
import com.microsoft.azure.batch.protocol.models.JobDisableParameter;
import com.microsoft.azure.batch.protocol.models.JobEnableHeaders;
import com.microsoft.azure.batch.protocol.models.JobEnableOptions;
import com.microsoft.azure.batch.protocol.models.JobGetHeaders;
import com.microsoft.azure.batch.protocol.models.JobGetOptions;
import com.microsoft.azure.batch.protocol.models.JobGetTaskCountsHeaders;
import com.microsoft.azure.batch.protocol.models.JobGetTaskCountsOptions;
import com.microsoft.azure.batch.protocol.models.JobListFromJobScheduleHeaders;
import com.microsoft.azure.batch.protocol.models.JobListFromJobScheduleNextOptions;
import com.microsoft.azure.batch.protocol.models.JobListFromJobScheduleOptions;
import com.microsoft.azure.batch.protocol.models.JobListHeaders;
import com.microsoft.azure.batch.protocol.models.JobListNextOptions;
import com.microsoft.azure.batch.protocol.models.JobListOptions;
import com.microsoft.azure.batch.protocol.models.JobListPreparationAndReleaseTaskStatusHeaders;
import com.microsoft.azure.batch.protocol.models.JobListPreparationAndReleaseTaskStatusNextOptions;
import com.microsoft.azure.batch.protocol.models.JobListPreparationAndReleaseTaskStatusOptions;
import com.microsoft.azure.batch.protocol.models.JobPatchHeaders;
import com.microsoft.azure.batch.protocol.models.JobPatchOptions;
import com.microsoft.azure.batch.protocol.models.JobPatchParameter;
import com.microsoft.azure.batch.protocol.models.JobPreparationAndReleaseTaskExecutionInformation;
import com.microsoft.azure.batch.protocol.models.JobTerminateHeaders;
import com.microsoft.azure.batch.protocol.models.JobTerminateOptions;
import com.microsoft.azure.batch.protocol.models.JobTerminateParameter;
import com.microsoft.azure.batch.protocol.models.JobUpdateHeaders;
import com.microsoft.azure.batch.protocol.models.JobUpdateOptions;
import com.microsoft.azure.batch.protocol.models.JobUpdateParameter;
import com.microsoft.azure.batch.protocol.models.PageImpl;
import com.microsoft.azure.batch.protocol.models.TaskCountsResult;
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.PATCH;
import retrofit2.http.Path;
import retrofit2.http.POST;
import retrofit2.http.PUT;
import retrofit2.http.Query;
import retrofit2.http.Url;
import retrofit2.Response;
import rx.functions.Func1;
import rx.Observable;

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

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

    /**
     * The interface defining all the services for Jobs to be
     * used by Retrofit to perform actually REST calls.
     */
    interface JobsService {
        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.batch.protocol.Jobs delete" })
        @HTTP(path = "jobs/{jobId}", method = "DELETE", hasBody = true)
        Observable<Response<ResponseBody>> delete(@Path("jobId") String jobId, @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("If-Match") String ifMatch, @Header("If-None-Match") String ifNoneMatch, @Header("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @Header("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @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.Jobs get" })
        @GET("jobs/{jobId}")
        Observable<Response<ResponseBody>> get(@Path("jobId") String jobId, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Query("$select") String select, @Query("$expand") String expand, @Query("timeout") Integer timeout, @Header("client-request-id") UUID clientRequestId, @Header("return-client-request-id") Boolean returnClientRequestId, @Header("ocp-date") DateTimeRfc1123 ocpDate, @Header("If-Match") String ifMatch, @Header("If-None-Match") String ifNoneMatch, @Header("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @Header("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; odata=minimalmetadata; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.batch.protocol.Jobs patch" })
        @PATCH("jobs/{jobId}")
        Observable<Response<ResponseBody>> patch(@Path("jobId") String jobId, @Body JobPatchParameter jobPatchParameter, @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("If-Match") String ifMatch, @Header("If-None-Match") String ifNoneMatch, @Header("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @Header("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; odata=minimalmetadata; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.batch.protocol.Jobs update" })
        @PUT("jobs/{jobId}")
        Observable<Response<ResponseBody>> update(@Path("jobId") String jobId, @Body JobUpdateParameter jobUpdateParameter, @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("If-Match") String ifMatch, @Header("If-None-Match") String ifNoneMatch, @Header("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @Header("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; odata=minimalmetadata; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.batch.protocol.Jobs disable" })
        @POST("jobs/{jobId}/disable")
        Observable<Response<ResponseBody>> disable(@Path("jobId") String jobId, @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("If-Match") String ifMatch, @Header("If-None-Match") String ifNoneMatch, @Header("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @Header("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @Body JobDisableParameter jobDisableParameter, @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.Jobs enable" })
        @POST("jobs/{jobId}/enable")
        Observable<Response<ResponseBody>> enable(@Path("jobId") String jobId, @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("If-Match") String ifMatch, @Header("If-None-Match") String ifNoneMatch, @Header("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @Header("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; odata=minimalmetadata; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.batch.protocol.Jobs terminate" })
        @POST("jobs/{jobId}/terminate")
        Observable<Response<ResponseBody>> terminate(@Path("jobId") String jobId, @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("If-Match") String ifMatch, @Header("If-None-Match") String ifNoneMatch, @Header("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @Header("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @Body JobTerminateParameter jobTerminateParameter, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; odata=minimalmetadata; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.batch.protocol.Jobs add" })
        @POST("jobs")
        Observable<Response<ResponseBody>> add(@Body JobAddParameter job, @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.Jobs list" })
        @GET("jobs")
        Observable<Response<ResponseBody>> list(@Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Query("$filter") String filter, @Query("$select") String select, @Query("$expand") String expand, @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.Jobs listFromJobSchedule" })
        @GET("jobschedules/{jobScheduleId}/jobs")
        Observable<Response<ResponseBody>> listFromJobSchedule(@Path("jobScheduleId") String jobScheduleId, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Query("$filter") String filter, @Query("$select") String select, @Query("$expand") String expand, @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.Jobs listPreparationAndReleaseTaskStatus" })
        @GET("jobs/{jobId}/jobpreparationandreleasetaskstatus")
        Observable<Response<ResponseBody>> listPreparationAndReleaseTaskStatus(@Path("jobId") String jobId, @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.Jobs getTaskCounts" })
        @GET("jobs/{jobId}/taskcounts")
        Observable<Response<ResponseBody>> getTaskCounts(@Path("jobId") String jobId, @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.Jobs 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);

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

    }

    /**
     * Deletes a Job.
     * Deleting a Job also deletes all Tasks that are part of that Job, and all Job statistics. This also overrides the retention period for Task data; that is, if the Job contains Tasks which are still retained on Compute Nodes, the Batch services deletes those Tasks' working directories and all their contents.  When a Delete Job request is received, the Batch service sets the Job to the deleting state. All update operations on a Job that is in deleting state will fail with status code 409 (Conflict), with additional information indicating that the Job is being deleted.
     *
     * @param jobId The ID of the Job to delete.
     * @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 jobId) {
        deleteWithServiceResponseAsync(jobId).toBlocking().single().body();
    }

    /**
     * Deletes a Job.
     * Deleting a Job also deletes all Tasks that are part of that Job, and all Job statistics. This also overrides the retention period for Task data; that is, if the Job contains Tasks which are still retained on Compute Nodes, the Batch services deletes those Tasks' working directories and all their contents.  When a Delete Job request is received, the Batch service sets the Job to the deleting state. All update operations on a Job that is in deleting state will fail with status code 409 (Conflict), with additional information indicating that the Job is being deleted.
     *
     * @param jobId The ID of the Job to delete.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<Void> deleteAsync(String jobId, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(deleteWithServiceResponseAsync(jobId), serviceCallback);
    }

    /**
     * Deletes a Job.
     * Deleting a Job also deletes all Tasks that are part of that Job, and all Job statistics. This also overrides the retention period for Task data; that is, if the Job contains Tasks which are still retained on Compute Nodes, the Batch services deletes those Tasks' working directories and all their contents.  When a Delete Job request is received, the Batch service sets the Job to the deleting state. All update operations on a Job that is in deleting state will fail with status code 409 (Conflict), with additional information indicating that the Job is being deleted.
     *
     * @param jobId The ID of the Job to delete.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> deleteAsync(String jobId) {
        return deleteWithServiceResponseAsync(jobId).map(new Func1<ServiceResponseWithHeaders<Void, JobDeleteHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, JobDeleteHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Deletes a Job.
     * Deleting a Job also deletes all Tasks that are part of that Job, and all Job statistics. This also overrides the retention period for Task data; that is, if the Job contains Tasks which are still retained on Compute Nodes, the Batch services deletes those Tasks' working directories and all their contents.  When a Delete Job request is received, the Batch service sets the Job to the deleting state. All update operations on a Job that is in deleting state will fail with status code 409 (Conflict), with additional information indicating that the Job is being deleted.
     *
     * @param jobId The ID of the Job to delete.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, JobDeleteHeaders>> deleteWithServiceResponseAsync(String jobId) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (jobId == null) {
            throw new IllegalArgumentException("Parameter jobId 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 JobDeleteOptions jobDeleteOptions = null;
        Integer timeout = null;
        UUID clientRequestId = null;
        Boolean returnClientRequestId = null;
        DateTime ocpDate = null;
        String ifMatch = null;
        String ifNoneMatch = null;
        DateTime ifModifiedSince = null;
        DateTime ifUnmodifiedSince = null;
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        DateTimeRfc1123 ifModifiedSinceConverted = null;
        if (ifModifiedSince != null) {
            ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince);
        }
        DateTimeRfc1123 ifUnmodifiedSinceConverted = null;
        if (ifUnmodifiedSince != null) {
            ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince);
        }
        return service.delete(jobId, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, ifMatch, ifNoneMatch, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, JobDeleteHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, JobDeleteHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, JobDeleteHeaders> clientResponse = deleteDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Deletes a Job.
     * Deleting a Job also deletes all Tasks that are part of that Job, and all Job statistics. This also overrides the retention period for Task data; that is, if the Job contains Tasks which are still retained on Compute Nodes, the Batch services deletes those Tasks' working directories and all their contents.  When a Delete Job request is received, the Batch service sets the Job to the deleting state. All update operations on a Job that is in deleting state will fail with status code 409 (Conflict), with additional information indicating that the Job is being deleted.
     *
     * @param jobId The ID of the Job to delete.
     * @param jobDeleteOptions 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 jobId, JobDeleteOptions jobDeleteOptions) {
        deleteWithServiceResponseAsync(jobId, jobDeleteOptions).toBlocking().single().body();
    }

    /**
     * Deletes a Job.
     * Deleting a Job also deletes all Tasks that are part of that Job, and all Job statistics. This also overrides the retention period for Task data; that is, if the Job contains Tasks which are still retained on Compute Nodes, the Batch services deletes those Tasks' working directories and all their contents.  When a Delete Job request is received, the Batch service sets the Job to the deleting state. All update operations on a Job that is in deleting state will fail with status code 409 (Conflict), with additional information indicating that the Job is being deleted.
     *
     * @param jobId The ID of the Job to delete.
     * @param jobDeleteOptions 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 jobId, JobDeleteOptions jobDeleteOptions, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(deleteWithServiceResponseAsync(jobId, jobDeleteOptions), serviceCallback);
    }

    /**
     * Deletes a Job.
     * Deleting a Job also deletes all Tasks that are part of that Job, and all Job statistics. This also overrides the retention period for Task data; that is, if the Job contains Tasks which are still retained on Compute Nodes, the Batch services deletes those Tasks' working directories and all their contents.  When a Delete Job request is received, the Batch service sets the Job to the deleting state. All update operations on a Job that is in deleting state will fail with status code 409 (Conflict), with additional information indicating that the Job is being deleted.
     *
     * @param jobId The ID of the Job to delete.
     * @param jobDeleteOptions 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 jobId, JobDeleteOptions jobDeleteOptions) {
        return deleteWithServiceResponseAsync(jobId, jobDeleteOptions).map(new Func1<ServiceResponseWithHeaders<Void, JobDeleteHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, JobDeleteHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Deletes a Job.
     * Deleting a Job also deletes all Tasks that are part of that Job, and all Job statistics. This also overrides the retention period for Task data; that is, if the Job contains Tasks which are still retained on Compute Nodes, the Batch services deletes those Tasks' working directories and all their contents.  When a Delete Job request is received, the Batch service sets the Job to the deleting state. All update operations on a Job that is in deleting state will fail with status code 409 (Conflict), with additional information indicating that the Job is being deleted.
     *
     * @param jobId The ID of the Job to delete.
     * @param jobDeleteOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, JobDeleteHeaders>> deleteWithServiceResponseAsync(String jobId, JobDeleteOptions jobDeleteOptions) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (jobId == null) {
            throw new IllegalArgumentException("Parameter jobId 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(jobDeleteOptions);
        Integer timeout = null;
        if (jobDeleteOptions != null) {
            timeout = jobDeleteOptions.timeout();
        }
        UUID clientRequestId = null;
        if (jobDeleteOptions != null) {
            clientRequestId = jobDeleteOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (jobDeleteOptions != null) {
            returnClientRequestId = jobDeleteOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (jobDeleteOptions != null) {
            ocpDate = jobDeleteOptions.ocpDate();
        }
        String ifMatch = null;
        if (jobDeleteOptions != null) {
            ifMatch = jobDeleteOptions.ifMatch();
        }
        String ifNoneMatch = null;
        if (jobDeleteOptions != null) {
            ifNoneMatch = jobDeleteOptions.ifNoneMatch();
        }
        DateTime ifModifiedSince = null;
        if (jobDeleteOptions != null) {
            ifModifiedSince = jobDeleteOptions.ifModifiedSince();
        }
        DateTime ifUnmodifiedSince = null;
        if (jobDeleteOptions != null) {
            ifUnmodifiedSince = jobDeleteOptions.ifUnmodifiedSince();
        }
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        DateTimeRfc1123 ifModifiedSinceConverted = null;
        if (ifModifiedSince != null) {
            ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince);
        }
        DateTimeRfc1123 ifUnmodifiedSinceConverted = null;
        if (ifUnmodifiedSince != null) {
            ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince);
        }
        return service.delete(jobId, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, ifMatch, ifNoneMatch, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, JobDeleteHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, JobDeleteHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, JobDeleteHeaders> clientResponse = deleteDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponseWithHeaders<Void, JobDeleteHeaders> 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, JobDeleteHeaders.class);
    }

    /**
     * Gets information about the specified Job.
     *
     * @param jobId The ID of the Job.
     * @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 CloudJob object if successful.
     */
    public CloudJob get(String jobId) {
        return getWithServiceResponseAsync(jobId).toBlocking().single().body();
    }

    /**
     * Gets information about the specified Job.
     *
     * @param jobId The ID of the Job.
     * @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<CloudJob> getAsync(String jobId, final ServiceCallback<CloudJob> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(getWithServiceResponseAsync(jobId), serviceCallback);
    }

    /**
     * Gets information about the specified Job.
     *
     * @param jobId The ID of the Job.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CloudJob object
     */
    public Observable<CloudJob> getAsync(String jobId) {
        return getWithServiceResponseAsync(jobId).map(new Func1<ServiceResponseWithHeaders<CloudJob, JobGetHeaders>, CloudJob>() {
            @Override
            public CloudJob call(ServiceResponseWithHeaders<CloudJob, JobGetHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets information about the specified Job.
     *
     * @param jobId The ID of the Job.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CloudJob object
     */
    public Observable<ServiceResponseWithHeaders<CloudJob, JobGetHeaders>> getWithServiceResponseAsync(String jobId) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (jobId == null) {
            throw new IllegalArgumentException("Parameter jobId 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 JobGetOptions jobGetOptions = null;
        String select = null;
        String expand = null;
        Integer timeout = null;
        UUID clientRequestId = null;
        Boolean returnClientRequestId = null;
        DateTime ocpDate = null;
        String ifMatch = null;
        String ifNoneMatch = null;
        DateTime ifModifiedSince = null;
        DateTime ifUnmodifiedSince = null;
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        DateTimeRfc1123 ifModifiedSinceConverted = null;
        if (ifModifiedSince != null) {
            ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince);
        }
        DateTimeRfc1123 ifUnmodifiedSinceConverted = null;
        if (ifUnmodifiedSince != null) {
            ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince);
        }
        return service.get(jobId, this.client.apiVersion(), this.client.acceptLanguage(), select, expand, timeout, clientRequestId, returnClientRequestId, ocpDateConverted, ifMatch, ifNoneMatch, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<CloudJob, JobGetHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<CloudJob, JobGetHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<CloudJob, JobGetHeaders> clientResponse = getDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Gets information about the specified Job.
     *
     * @param jobId The ID of the Job.
     * @param jobGetOptions 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 CloudJob object if successful.
     */
    public CloudJob get(String jobId, JobGetOptions jobGetOptions) {
        return getWithServiceResponseAsync(jobId, jobGetOptions).toBlocking().single().body();
    }

    /**
     * Gets information about the specified Job.
     *
     * @param jobId The ID of the Job.
     * @param jobGetOptions 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<CloudJob> getAsync(String jobId, JobGetOptions jobGetOptions, final ServiceCallback<CloudJob> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(getWithServiceResponseAsync(jobId, jobGetOptions), serviceCallback);
    }

    /**
     * Gets information about the specified Job.
     *
     * @param jobId The ID of the Job.
     * @param jobGetOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CloudJob object
     */
    public Observable<CloudJob> getAsync(String jobId, JobGetOptions jobGetOptions) {
        return getWithServiceResponseAsync(jobId, jobGetOptions).map(new Func1<ServiceResponseWithHeaders<CloudJob, JobGetHeaders>, CloudJob>() {
            @Override
            public CloudJob call(ServiceResponseWithHeaders<CloudJob, JobGetHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets information about the specified Job.
     *
     * @param jobId The ID of the Job.
     * @param jobGetOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CloudJob object
     */
    public Observable<ServiceResponseWithHeaders<CloudJob, JobGetHeaders>> getWithServiceResponseAsync(String jobId, JobGetOptions jobGetOptions) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (jobId == null) {
            throw new IllegalArgumentException("Parameter jobId 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(jobGetOptions);
        String select = null;
        if (jobGetOptions != null) {
            select = jobGetOptions.select();
        }
        String expand = null;
        if (jobGetOptions != null) {
            expand = jobGetOptions.expand();
        }
        Integer timeout = null;
        if (jobGetOptions != null) {
            timeout = jobGetOptions.timeout();
        }
        UUID clientRequestId = null;
        if (jobGetOptions != null) {
            clientRequestId = jobGetOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (jobGetOptions != null) {
            returnClientRequestId = jobGetOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (jobGetOptions != null) {
            ocpDate = jobGetOptions.ocpDate();
        }
        String ifMatch = null;
        if (jobGetOptions != null) {
            ifMatch = jobGetOptions.ifMatch();
        }
        String ifNoneMatch = null;
        if (jobGetOptions != null) {
            ifNoneMatch = jobGetOptions.ifNoneMatch();
        }
        DateTime ifModifiedSince = null;
        if (jobGetOptions != null) {
            ifModifiedSince = jobGetOptions.ifModifiedSince();
        }
        DateTime ifUnmodifiedSince = null;
        if (jobGetOptions != null) {
            ifUnmodifiedSince = jobGetOptions.ifUnmodifiedSince();
        }
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        DateTimeRfc1123 ifModifiedSinceConverted = null;
        if (ifModifiedSince != null) {
            ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince);
        }
        DateTimeRfc1123 ifUnmodifiedSinceConverted = null;
        if (ifUnmodifiedSince != null) {
            ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince);
        }
        return service.get(jobId, this.client.apiVersion(), this.client.acceptLanguage(), select, expand, timeout, clientRequestId, returnClientRequestId, ocpDateConverted, ifMatch, ifNoneMatch, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<CloudJob, JobGetHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<CloudJob, JobGetHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<CloudJob, JobGetHeaders> clientResponse = getDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Updates the properties of the specified Job.
     * This replaces only the Job properties specified in the request. For example, if the Job has constraints, and a request does not specify the constraints element, then the Job keeps the existing constraints.
     *
     * @param jobId The ID of the Job whose properties you want to update.
     * @param jobPatchParameter The parameters for the request.
     * @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 patch(String jobId, JobPatchParameter jobPatchParameter) {
        patchWithServiceResponseAsync(jobId, jobPatchParameter).toBlocking().single().body();
    }

    /**
     * Updates the properties of the specified Job.
     * This replaces only the Job properties specified in the request. For example, if the Job has constraints, and a request does not specify the constraints element, then the Job keeps the existing constraints.
     *
     * @param jobId The ID of the Job whose properties you want to update.
     * @param jobPatchParameter The parameters for the request.
     * @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> patchAsync(String jobId, JobPatchParameter jobPatchParameter, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(patchWithServiceResponseAsync(jobId, jobPatchParameter), serviceCallback);
    }

    /**
     * Updates the properties of the specified Job.
     * This replaces only the Job properties specified in the request. For example, if the Job has constraints, and a request does not specify the constraints element, then the Job keeps the existing constraints.
     *
     * @param jobId The ID of the Job whose properties you want to update.
     * @param jobPatchParameter The parameters for the request.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> patchAsync(String jobId, JobPatchParameter jobPatchParameter) {
        return patchWithServiceResponseAsync(jobId, jobPatchParameter).map(new Func1<ServiceResponseWithHeaders<Void, JobPatchHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, JobPatchHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates the properties of the specified Job.
     * This replaces only the Job properties specified in the request. For example, if the Job has constraints, and a request does not specify the constraints element, then the Job keeps the existing constraints.
     *
     * @param jobId The ID of the Job whose properties you want to update.
     * @param jobPatchParameter The parameters for the request.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, JobPatchHeaders>> patchWithServiceResponseAsync(String jobId, JobPatchParameter jobPatchParameter) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (jobId == null) {
            throw new IllegalArgumentException("Parameter jobId is required and cannot be null.");
        }
        if (jobPatchParameter == null) {
            throw new IllegalArgumentException("Parameter jobPatchParameter 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(jobPatchParameter);
        final JobPatchOptions jobPatchOptions = null;
        Integer timeout = null;
        UUID clientRequestId = null;
        Boolean returnClientRequestId = null;
        DateTime ocpDate = null;
        String ifMatch = null;
        String ifNoneMatch = null;
        DateTime ifModifiedSince = null;
        DateTime ifUnmodifiedSince = null;
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        DateTimeRfc1123 ifModifiedSinceConverted = null;
        if (ifModifiedSince != null) {
            ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince);
        }
        DateTimeRfc1123 ifUnmodifiedSinceConverted = null;
        if (ifUnmodifiedSince != null) {
            ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince);
        }
        return service.patch(jobId, jobPatchParameter, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, ifMatch, ifNoneMatch, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, JobPatchHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, JobPatchHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, JobPatchHeaders> clientResponse = patchDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Updates the properties of the specified Job.
     * This replaces only the Job properties specified in the request. For example, if the Job has constraints, and a request does not specify the constraints element, then the Job keeps the existing constraints.
     *
     * @param jobId The ID of the Job whose properties you want to update.
     * @param jobPatchParameter The parameters for the request.
     * @param jobPatchOptions 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 patch(String jobId, JobPatchParameter jobPatchParameter, JobPatchOptions jobPatchOptions) {
        patchWithServiceResponseAsync(jobId, jobPatchParameter, jobPatchOptions).toBlocking().single().body();
    }

    /**
     * Updates the properties of the specified Job.
     * This replaces only the Job properties specified in the request. For example, if the Job has constraints, and a request does not specify the constraints element, then the Job keeps the existing constraints.
     *
     * @param jobId The ID of the Job whose properties you want to update.
     * @param jobPatchParameter The parameters for the request.
     * @param jobPatchOptions 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> patchAsync(String jobId, JobPatchParameter jobPatchParameter, JobPatchOptions jobPatchOptions, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(patchWithServiceResponseAsync(jobId, jobPatchParameter, jobPatchOptions), serviceCallback);
    }

    /**
     * Updates the properties of the specified Job.
     * This replaces only the Job properties specified in the request. For example, if the Job has constraints, and a request does not specify the constraints element, then the Job keeps the existing constraints.
     *
     * @param jobId The ID of the Job whose properties you want to update.
     * @param jobPatchParameter The parameters for the request.
     * @param jobPatchOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> patchAsync(String jobId, JobPatchParameter jobPatchParameter, JobPatchOptions jobPatchOptions) {
        return patchWithServiceResponseAsync(jobId, jobPatchParameter, jobPatchOptions).map(new Func1<ServiceResponseWithHeaders<Void, JobPatchHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, JobPatchHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates the properties of the specified Job.
     * This replaces only the Job properties specified in the request. For example, if the Job has constraints, and a request does not specify the constraints element, then the Job keeps the existing constraints.
     *
     * @param jobId The ID of the Job whose properties you want to update.
     * @param jobPatchParameter The parameters for the request.
     * @param jobPatchOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, JobPatchHeaders>> patchWithServiceResponseAsync(String jobId, JobPatchParameter jobPatchParameter, JobPatchOptions jobPatchOptions) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (jobId == null) {
            throw new IllegalArgumentException("Parameter jobId is required and cannot be null.");
        }
        if (jobPatchParameter == null) {
            throw new IllegalArgumentException("Parameter jobPatchParameter 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(jobPatchParameter);
        Validator.validate(jobPatchOptions);
        Integer timeout = null;
        if (jobPatchOptions != null) {
            timeout = jobPatchOptions.timeout();
        }
        UUID clientRequestId = null;
        if (jobPatchOptions != null) {
            clientRequestId = jobPatchOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (jobPatchOptions != null) {
            returnClientRequestId = jobPatchOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (jobPatchOptions != null) {
            ocpDate = jobPatchOptions.ocpDate();
        }
        String ifMatch = null;
        if (jobPatchOptions != null) {
            ifMatch = jobPatchOptions.ifMatch();
        }
        String ifNoneMatch = null;
        if (jobPatchOptions != null) {
            ifNoneMatch = jobPatchOptions.ifNoneMatch();
        }
        DateTime ifModifiedSince = null;
        if (jobPatchOptions != null) {
            ifModifiedSince = jobPatchOptions.ifModifiedSince();
        }
        DateTime ifUnmodifiedSince = null;
        if (jobPatchOptions != null) {
            ifUnmodifiedSince = jobPatchOptions.ifUnmodifiedSince();
        }
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        DateTimeRfc1123 ifModifiedSinceConverted = null;
        if (ifModifiedSince != null) {
            ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince);
        }
        DateTimeRfc1123 ifUnmodifiedSinceConverted = null;
        if (ifUnmodifiedSince != null) {
            ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince);
        }
        return service.patch(jobId, jobPatchParameter, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, ifMatch, ifNoneMatch, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, JobPatchHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, JobPatchHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, JobPatchHeaders> clientResponse = patchDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Updates the properties of the specified Job.
     * This fully replaces all the updatable properties of the Job. For example, if the Job has constraints associated with it and if constraints is not specified with this request, then the Batch service will remove the existing constraints.
     *
     * @param jobId The ID of the Job whose properties you want to update.
     * @param jobUpdateParameter The parameters for the request.
     * @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 update(String jobId, JobUpdateParameter jobUpdateParameter) {
        updateWithServiceResponseAsync(jobId, jobUpdateParameter).toBlocking().single().body();
    }

    /**
     * Updates the properties of the specified Job.
     * This fully replaces all the updatable properties of the Job. For example, if the Job has constraints associated with it and if constraints is not specified with this request, then the Batch service will remove the existing constraints.
     *
     * @param jobId The ID of the Job whose properties you want to update.
     * @param jobUpdateParameter The parameters for the request.
     * @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> updateAsync(String jobId, JobUpdateParameter jobUpdateParameter, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(updateWithServiceResponseAsync(jobId, jobUpdateParameter), serviceCallback);
    }

    /**
     * Updates the properties of the specified Job.
     * This fully replaces all the updatable properties of the Job. For example, if the Job has constraints associated with it and if constraints is not specified with this request, then the Batch service will remove the existing constraints.
     *
     * @param jobId The ID of the Job whose properties you want to update.
     * @param jobUpdateParameter The parameters for the request.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> updateAsync(String jobId, JobUpdateParameter jobUpdateParameter) {
        return updateWithServiceResponseAsync(jobId, jobUpdateParameter).map(new Func1<ServiceResponseWithHeaders<Void, JobUpdateHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, JobUpdateHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates the properties of the specified Job.
     * This fully replaces all the updatable properties of the Job. For example, if the Job has constraints associated with it and if constraints is not specified with this request, then the Batch service will remove the existing constraints.
     *
     * @param jobId The ID of the Job whose properties you want to update.
     * @param jobUpdateParameter The parameters for the request.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, JobUpdateHeaders>> updateWithServiceResponseAsync(String jobId, JobUpdateParameter jobUpdateParameter) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (jobId == null) {
            throw new IllegalArgumentException("Parameter jobId is required and cannot be null.");
        }
        if (jobUpdateParameter == null) {
            throw new IllegalArgumentException("Parameter jobUpdateParameter 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(jobUpdateParameter);
        final JobUpdateOptions jobUpdateOptions = null;
        Integer timeout = null;
        UUID clientRequestId = null;
        Boolean returnClientRequestId = null;
        DateTime ocpDate = null;
        String ifMatch = null;
        String ifNoneMatch = null;
        DateTime ifModifiedSince = null;
        DateTime ifUnmodifiedSince = null;
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        DateTimeRfc1123 ifModifiedSinceConverted = null;
        if (ifModifiedSince != null) {
            ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince);
        }
        DateTimeRfc1123 ifUnmodifiedSinceConverted = null;
        if (ifUnmodifiedSince != null) {
            ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince);
        }
        return service.update(jobId, jobUpdateParameter, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, ifMatch, ifNoneMatch, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, JobUpdateHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, JobUpdateHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, JobUpdateHeaders> clientResponse = updateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Updates the properties of the specified Job.
     * This fully replaces all the updatable properties of the Job. For example, if the Job has constraints associated with it and if constraints is not specified with this request, then the Batch service will remove the existing constraints.
     *
     * @param jobId The ID of the Job whose properties you want to update.
     * @param jobUpdateParameter The parameters for the request.
     * @param jobUpdateOptions 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 update(String jobId, JobUpdateParameter jobUpdateParameter, JobUpdateOptions jobUpdateOptions) {
        updateWithServiceResponseAsync(jobId, jobUpdateParameter, jobUpdateOptions).toBlocking().single().body();
    }

    /**
     * Updates the properties of the specified Job.
     * This fully replaces all the updatable properties of the Job. For example, if the Job has constraints associated with it and if constraints is not specified with this request, then the Batch service will remove the existing constraints.
     *
     * @param jobId The ID of the Job whose properties you want to update.
     * @param jobUpdateParameter The parameters for the request.
     * @param jobUpdateOptions 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> updateAsync(String jobId, JobUpdateParameter jobUpdateParameter, JobUpdateOptions jobUpdateOptions, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(updateWithServiceResponseAsync(jobId, jobUpdateParameter, jobUpdateOptions), serviceCallback);
    }

    /**
     * Updates the properties of the specified Job.
     * This fully replaces all the updatable properties of the Job. For example, if the Job has constraints associated with it and if constraints is not specified with this request, then the Batch service will remove the existing constraints.
     *
     * @param jobId The ID of the Job whose properties you want to update.
     * @param jobUpdateParameter The parameters for the request.
     * @param jobUpdateOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> updateAsync(String jobId, JobUpdateParameter jobUpdateParameter, JobUpdateOptions jobUpdateOptions) {
        return updateWithServiceResponseAsync(jobId, jobUpdateParameter, jobUpdateOptions).map(new Func1<ServiceResponseWithHeaders<Void, JobUpdateHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, JobUpdateHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates the properties of the specified Job.
     * This fully replaces all the updatable properties of the Job. For example, if the Job has constraints associated with it and if constraints is not specified with this request, then the Batch service will remove the existing constraints.
     *
     * @param jobId The ID of the Job whose properties you want to update.
     * @param jobUpdateParameter The parameters for the request.
     * @param jobUpdateOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, JobUpdateHeaders>> updateWithServiceResponseAsync(String jobId, JobUpdateParameter jobUpdateParameter, JobUpdateOptions jobUpdateOptions) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (jobId == null) {
            throw new IllegalArgumentException("Parameter jobId is required and cannot be null.");
        }
        if (jobUpdateParameter == null) {
            throw new IllegalArgumentException("Parameter jobUpdateParameter 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(jobUpdateParameter);
        Validator.validate(jobUpdateOptions);
        Integer timeout = null;
        if (jobUpdateOptions != null) {
            timeout = jobUpdateOptions.timeout();
        }
        UUID clientRequestId = null;
        if (jobUpdateOptions != null) {
            clientRequestId = jobUpdateOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (jobUpdateOptions != null) {
            returnClientRequestId = jobUpdateOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (jobUpdateOptions != null) {
            ocpDate = jobUpdateOptions.ocpDate();
        }
        String ifMatch = null;
        if (jobUpdateOptions != null) {
            ifMatch = jobUpdateOptions.ifMatch();
        }
        String ifNoneMatch = null;
        if (jobUpdateOptions != null) {
            ifNoneMatch = jobUpdateOptions.ifNoneMatch();
        }
        DateTime ifModifiedSince = null;
        if (jobUpdateOptions != null) {
            ifModifiedSince = jobUpdateOptions.ifModifiedSince();
        }
        DateTime ifUnmodifiedSince = null;
        if (jobUpdateOptions != null) {
            ifUnmodifiedSince = jobUpdateOptions.ifUnmodifiedSince();
        }
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        DateTimeRfc1123 ifModifiedSinceConverted = null;
        if (ifModifiedSince != null) {
            ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince);
        }
        DateTimeRfc1123 ifUnmodifiedSinceConverted = null;
        if (ifUnmodifiedSince != null) {
            ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince);
        }
        return service.update(jobId, jobUpdateParameter, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, ifMatch, ifNoneMatch, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, JobUpdateHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, JobUpdateHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, JobUpdateHeaders> clientResponse = updateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Disables the specified Job, preventing new Tasks from running.
     * The Batch Service immediately moves the Job to the disabling state. Batch then uses the disableTasks parameter to determine what to do with the currently running Tasks of the Job. The Job remains in the disabling state until the disable operation is completed and all Tasks have been dealt with according to the disableTasks option; the Job then moves to the disabled state. No new Tasks are started under the Job until it moves back to active state. If you try to disable a Job that is in any state other than active, disabling, or disabled, the request fails with status code 409.
     *
     * @param jobId The ID of the Job to disable.
     * @param disableTasks What to do with active Tasks associated with the Job. Possible values include: 'requeue', 'terminate', 'wait'
     * @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 disable(String jobId, DisableJobOption disableTasks) {
        disableWithServiceResponseAsync(jobId, disableTasks).toBlocking().single().body();
    }

    /**
     * Disables the specified Job, preventing new Tasks from running.
     * The Batch Service immediately moves the Job to the disabling state. Batch then uses the disableTasks parameter to determine what to do with the currently running Tasks of the Job. The Job remains in the disabling state until the disable operation is completed and all Tasks have been dealt with according to the disableTasks option; the Job then moves to the disabled state. No new Tasks are started under the Job until it moves back to active state. If you try to disable a Job that is in any state other than active, disabling, or disabled, the request fails with status code 409.
     *
     * @param jobId The ID of the Job to disable.
     * @param disableTasks What to do with active Tasks associated with the Job. Possible values include: 'requeue', 'terminate', 'wait'
     * @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> disableAsync(String jobId, DisableJobOption disableTasks, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(disableWithServiceResponseAsync(jobId, disableTasks), serviceCallback);
    }

    /**
     * Disables the specified Job, preventing new Tasks from running.
     * The Batch Service immediately moves the Job to the disabling state. Batch then uses the disableTasks parameter to determine what to do with the currently running Tasks of the Job. The Job remains in the disabling state until the disable operation is completed and all Tasks have been dealt with according to the disableTasks option; the Job then moves to the disabled state. No new Tasks are started under the Job until it moves back to active state. If you try to disable a Job that is in any state other than active, disabling, or disabled, the request fails with status code 409.
     *
     * @param jobId The ID of the Job to disable.
     * @param disableTasks What to do with active Tasks associated with the Job. Possible values include: 'requeue', 'terminate', 'wait'
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> disableAsync(String jobId, DisableJobOption disableTasks) {
        return disableWithServiceResponseAsync(jobId, disableTasks).map(new Func1<ServiceResponseWithHeaders<Void, JobDisableHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, JobDisableHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Disables the specified Job, preventing new Tasks from running.
     * The Batch Service immediately moves the Job to the disabling state. Batch then uses the disableTasks parameter to determine what to do with the currently running Tasks of the Job. The Job remains in the disabling state until the disable operation is completed and all Tasks have been dealt with according to the disableTasks option; the Job then moves to the disabled state. No new Tasks are started under the Job until it moves back to active state. If you try to disable a Job that is in any state other than active, disabling, or disabled, the request fails with status code 409.
     *
     * @param jobId The ID of the Job to disable.
     * @param disableTasks What to do with active Tasks associated with the Job. Possible values include: 'requeue', 'terminate', 'wait'
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, JobDisableHeaders>> disableWithServiceResponseAsync(String jobId, DisableJobOption disableTasks) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (jobId == null) {
            throw new IllegalArgumentException("Parameter jobId is required and cannot be null.");
        }
        if (this.client.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.client.apiVersion() is required and cannot be null.");
        }
        if (disableTasks == null) {
            throw new IllegalArgumentException("Parameter disableTasks is required and cannot be null.");
        }
        final JobDisableOptions jobDisableOptions = null;
        Integer timeout = null;
        UUID clientRequestId = null;
        Boolean returnClientRequestId = null;
        DateTime ocpDate = null;
        String ifMatch = null;
        String ifNoneMatch = null;
        DateTime ifModifiedSince = null;
        DateTime ifUnmodifiedSince = null;
        JobDisableParameter jobDisableParameter = new JobDisableParameter();
        jobDisableParameter.withDisableTasks(disableTasks);
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        DateTimeRfc1123 ifModifiedSinceConverted = null;
        if (ifModifiedSince != null) {
            ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince);
        }
        DateTimeRfc1123 ifUnmodifiedSinceConverted = null;
        if (ifUnmodifiedSince != null) {
            ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince);
        }
        return service.disable(jobId, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, ifMatch, ifNoneMatch, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, jobDisableParameter, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, JobDisableHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, JobDisableHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, JobDisableHeaders> clientResponse = disableDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Disables the specified Job, preventing new Tasks from running.
     * The Batch Service immediately moves the Job to the disabling state. Batch then uses the disableTasks parameter to determine what to do with the currently running Tasks of the Job. The Job remains in the disabling state until the disable operation is completed and all Tasks have been dealt with according to the disableTasks option; the Job then moves to the disabled state. No new Tasks are started under the Job until it moves back to active state. If you try to disable a Job that is in any state other than active, disabling, or disabled, the request fails with status code 409.
     *
     * @param jobId The ID of the Job to disable.
     * @param disableTasks What to do with active Tasks associated with the Job. Possible values include: 'requeue', 'terminate', 'wait'
     * @param jobDisableOptions 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 disable(String jobId, DisableJobOption disableTasks, JobDisableOptions jobDisableOptions) {
        disableWithServiceResponseAsync(jobId, disableTasks, jobDisableOptions).toBlocking().single().body();
    }

    /**
     * Disables the specified Job, preventing new Tasks from running.
     * The Batch Service immediately moves the Job to the disabling state. Batch then uses the disableTasks parameter to determine what to do with the currently running Tasks of the Job. The Job remains in the disabling state until the disable operation is completed and all Tasks have been dealt with according to the disableTasks option; the Job then moves to the disabled state. No new Tasks are started under the Job until it moves back to active state. If you try to disable a Job that is in any state other than active, disabling, or disabled, the request fails with status code 409.
     *
     * @param jobId The ID of the Job to disable.
     * @param disableTasks What to do with active Tasks associated with the Job. Possible values include: 'requeue', 'terminate', 'wait'
     * @param jobDisableOptions 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> disableAsync(String jobId, DisableJobOption disableTasks, JobDisableOptions jobDisableOptions, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(disableWithServiceResponseAsync(jobId, disableTasks, jobDisableOptions), serviceCallback);
    }

    /**
     * Disables the specified Job, preventing new Tasks from running.
     * The Batch Service immediately moves the Job to the disabling state. Batch then uses the disableTasks parameter to determine what to do with the currently running Tasks of the Job. The Job remains in the disabling state until the disable operation is completed and all Tasks have been dealt with according to the disableTasks option; the Job then moves to the disabled state. No new Tasks are started under the Job until it moves back to active state. If you try to disable a Job that is in any state other than active, disabling, or disabled, the request fails with status code 409.
     *
     * @param jobId The ID of the Job to disable.
     * @param disableTasks What to do with active Tasks associated with the Job. Possible values include: 'requeue', 'terminate', 'wait'
     * @param jobDisableOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> disableAsync(String jobId, DisableJobOption disableTasks, JobDisableOptions jobDisableOptions) {
        return disableWithServiceResponseAsync(jobId, disableTasks, jobDisableOptions).map(new Func1<ServiceResponseWithHeaders<Void, JobDisableHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, JobDisableHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Disables the specified Job, preventing new Tasks from running.
     * The Batch Service immediately moves the Job to the disabling state. Batch then uses the disableTasks parameter to determine what to do with the currently running Tasks of the Job. The Job remains in the disabling state until the disable operation is completed and all Tasks have been dealt with according to the disableTasks option; the Job then moves to the disabled state. No new Tasks are started under the Job until it moves back to active state. If you try to disable a Job that is in any state other than active, disabling, or disabled, the request fails with status code 409.
     *
     * @param jobId The ID of the Job to disable.
     * @param disableTasks What to do with active Tasks associated with the Job. Possible values include: 'requeue', 'terminate', 'wait'
     * @param jobDisableOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, JobDisableHeaders>> disableWithServiceResponseAsync(String jobId, DisableJobOption disableTasks, JobDisableOptions jobDisableOptions) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (jobId == null) {
            throw new IllegalArgumentException("Parameter jobId is required and cannot be null.");
        }
        if (this.client.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.client.apiVersion() is required and cannot be null.");
        }
        if (disableTasks == null) {
            throw new IllegalArgumentException("Parameter disableTasks is required and cannot be null.");
        }
        Validator.validate(jobDisableOptions);
        Integer timeout = null;
        if (jobDisableOptions != null) {
            timeout = jobDisableOptions.timeout();
        }
        UUID clientRequestId = null;
        if (jobDisableOptions != null) {
            clientRequestId = jobDisableOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (jobDisableOptions != null) {
            returnClientRequestId = jobDisableOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (jobDisableOptions != null) {
            ocpDate = jobDisableOptions.ocpDate();
        }
        String ifMatch = null;
        if (jobDisableOptions != null) {
            ifMatch = jobDisableOptions.ifMatch();
        }
        String ifNoneMatch = null;
        if (jobDisableOptions != null) {
            ifNoneMatch = jobDisableOptions.ifNoneMatch();
        }
        DateTime ifModifiedSince = null;
        if (jobDisableOptions != null) {
            ifModifiedSince = jobDisableOptions.ifModifiedSince();
        }
        DateTime ifUnmodifiedSince = null;
        if (jobDisableOptions != null) {
            ifUnmodifiedSince = jobDisableOptions.ifUnmodifiedSince();
        }
        JobDisableParameter jobDisableParameter = new JobDisableParameter();
        jobDisableParameter.withDisableTasks(disableTasks);
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        DateTimeRfc1123 ifModifiedSinceConverted = null;
        if (ifModifiedSince != null) {
            ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince);
        }
        DateTimeRfc1123 ifUnmodifiedSinceConverted = null;
        if (ifUnmodifiedSince != null) {
            ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince);
        }
        return service.disable(jobId, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, ifMatch, ifNoneMatch, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, jobDisableParameter, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, JobDisableHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, JobDisableHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, JobDisableHeaders> clientResponse = disableDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponseWithHeaders<Void, JobDisableHeaders> disableDelegate(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, JobDisableHeaders.class);
    }

    /**
     * Enables the specified Job, allowing new Tasks to run.
     * When you call this API, the Batch service sets a disabled Job to the enabling state. After the this operation is completed, the Job moves to the active state, and scheduling of new Tasks under the Job resumes. The Batch service does not allow a Task to remain in the active state for more than 180 days. Therefore, if you enable a Job containing active Tasks which were added more than 180 days ago, those Tasks will not run.
     *
     * @param jobId The ID of the Job to enable.
     * @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 enable(String jobId) {
        enableWithServiceResponseAsync(jobId).toBlocking().single().body();
    }

    /**
     * Enables the specified Job, allowing new Tasks to run.
     * When you call this API, the Batch service sets a disabled Job to the enabling state. After the this operation is completed, the Job moves to the active state, and scheduling of new Tasks under the Job resumes. The Batch service does not allow a Task to remain in the active state for more than 180 days. Therefore, if you enable a Job containing active Tasks which were added more than 180 days ago, those Tasks will not run.
     *
     * @param jobId The ID of the Job to enable.
     * @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> enableAsync(String jobId, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(enableWithServiceResponseAsync(jobId), serviceCallback);
    }

    /**
     * Enables the specified Job, allowing new Tasks to run.
     * When you call this API, the Batch service sets a disabled Job to the enabling state. After the this operation is completed, the Job moves to the active state, and scheduling of new Tasks under the Job resumes. The Batch service does not allow a Task to remain in the active state for more than 180 days. Therefore, if you enable a Job containing active Tasks which were added more than 180 days ago, those Tasks will not run.
     *
     * @param jobId The ID of the Job to enable.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> enableAsync(String jobId) {
        return enableWithServiceResponseAsync(jobId).map(new Func1<ServiceResponseWithHeaders<Void, JobEnableHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, JobEnableHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Enables the specified Job, allowing new Tasks to run.
     * When you call this API, the Batch service sets a disabled Job to the enabling state. After the this operation is completed, the Job moves to the active state, and scheduling of new Tasks under the Job resumes. The Batch service does not allow a Task to remain in the active state for more than 180 days. Therefore, if you enable a Job containing active Tasks which were added more than 180 days ago, those Tasks will not run.
     *
     * @param jobId The ID of the Job to enable.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, JobEnableHeaders>> enableWithServiceResponseAsync(String jobId) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (jobId == null) {
            throw new IllegalArgumentException("Parameter jobId 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 JobEnableOptions jobEnableOptions = null;
        Integer timeout = null;
        UUID clientRequestId = null;
        Boolean returnClientRequestId = null;
        DateTime ocpDate = null;
        String ifMatch = null;
        String ifNoneMatch = null;
        DateTime ifModifiedSince = null;
        DateTime ifUnmodifiedSince = null;
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        DateTimeRfc1123 ifModifiedSinceConverted = null;
        if (ifModifiedSince != null) {
            ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince);
        }
        DateTimeRfc1123 ifUnmodifiedSinceConverted = null;
        if (ifUnmodifiedSince != null) {
            ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince);
        }
        return service.enable(jobId, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, ifMatch, ifNoneMatch, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, JobEnableHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, JobEnableHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, JobEnableHeaders> clientResponse = enableDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Enables the specified Job, allowing new Tasks to run.
     * When you call this API, the Batch service sets a disabled Job to the enabling state. After the this operation is completed, the Job moves to the active state, and scheduling of new Tasks under the Job resumes. The Batch service does not allow a Task to remain in the active state for more than 180 days. Therefore, if you enable a Job containing active Tasks which were added more than 180 days ago, those Tasks will not run.
     *
     * @param jobId The ID of the Job to enable.
     * @param jobEnableOptions 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 enable(String jobId, JobEnableOptions jobEnableOptions) {
        enableWithServiceResponseAsync(jobId, jobEnableOptions).toBlocking().single().body();
    }

    /**
     * Enables the specified Job, allowing new Tasks to run.
     * When you call this API, the Batch service sets a disabled Job to the enabling state. After the this operation is completed, the Job moves to the active state, and scheduling of new Tasks under the Job resumes. The Batch service does not allow a Task to remain in the active state for more than 180 days. Therefore, if you enable a Job containing active Tasks which were added more than 180 days ago, those Tasks will not run.
     *
     * @param jobId The ID of the Job to enable.
     * @param jobEnableOptions 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> enableAsync(String jobId, JobEnableOptions jobEnableOptions, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(enableWithServiceResponseAsync(jobId, jobEnableOptions), serviceCallback);
    }

    /**
     * Enables the specified Job, allowing new Tasks to run.
     * When you call this API, the Batch service sets a disabled Job to the enabling state. After the this operation is completed, the Job moves to the active state, and scheduling of new Tasks under the Job resumes. The Batch service does not allow a Task to remain in the active state for more than 180 days. Therefore, if you enable a Job containing active Tasks which were added more than 180 days ago, those Tasks will not run.
     *
     * @param jobId The ID of the Job to enable.
     * @param jobEnableOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> enableAsync(String jobId, JobEnableOptions jobEnableOptions) {
        return enableWithServiceResponseAsync(jobId, jobEnableOptions).map(new Func1<ServiceResponseWithHeaders<Void, JobEnableHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, JobEnableHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Enables the specified Job, allowing new Tasks to run.
     * When you call this API, the Batch service sets a disabled Job to the enabling state. After the this operation is completed, the Job moves to the active state, and scheduling of new Tasks under the Job resumes. The Batch service does not allow a Task to remain in the active state for more than 180 days. Therefore, if you enable a Job containing active Tasks which were added more than 180 days ago, those Tasks will not run.
     *
     * @param jobId The ID of the Job to enable.
     * @param jobEnableOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, JobEnableHeaders>> enableWithServiceResponseAsync(String jobId, JobEnableOptions jobEnableOptions) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (jobId == null) {
            throw new IllegalArgumentException("Parameter jobId 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(jobEnableOptions);
        Integer timeout = null;
        if (jobEnableOptions != null) {
            timeout = jobEnableOptions.timeout();
        }
        UUID clientRequestId = null;
        if (jobEnableOptions != null) {
            clientRequestId = jobEnableOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (jobEnableOptions != null) {
            returnClientRequestId = jobEnableOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (jobEnableOptions != null) {
            ocpDate = jobEnableOptions.ocpDate();
        }
        String ifMatch = null;
        if (jobEnableOptions != null) {
            ifMatch = jobEnableOptions.ifMatch();
        }
        String ifNoneMatch = null;
        if (jobEnableOptions != null) {
            ifNoneMatch = jobEnableOptions.ifNoneMatch();
        }
        DateTime ifModifiedSince = null;
        if (jobEnableOptions != null) {
            ifModifiedSince = jobEnableOptions.ifModifiedSince();
        }
        DateTime ifUnmodifiedSince = null;
        if (jobEnableOptions != null) {
            ifUnmodifiedSince = jobEnableOptions.ifUnmodifiedSince();
        }
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        DateTimeRfc1123 ifModifiedSinceConverted = null;
        if (ifModifiedSince != null) {
            ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince);
        }
        DateTimeRfc1123 ifUnmodifiedSinceConverted = null;
        if (ifUnmodifiedSince != null) {
            ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince);
        }
        return service.enable(jobId, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, ifMatch, ifNoneMatch, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, JobEnableHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, JobEnableHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, JobEnableHeaders> clientResponse = enableDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponseWithHeaders<Void, JobEnableHeaders> enableDelegate(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, JobEnableHeaders.class);
    }

    /**
     * Terminates the specified Job, marking it as completed.
     * When a Terminate Job request is received, the Batch service sets the Job to the terminating state. The Batch service then terminates any running Tasks associated with the Job and runs any required Job release Tasks. Then the Job moves into the completed state. If there are any Tasks in the Job in the active state, they will remain in the active state. Once a Job is terminated, new Tasks cannot be added and any remaining active Tasks will not be scheduled.
     *
     * @param jobId The ID of the Job to terminate.
     * @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 terminate(String jobId) {
        terminateWithServiceResponseAsync(jobId).toBlocking().single().body();
    }

    /**
     * Terminates the specified Job, marking it as completed.
     * When a Terminate Job request is received, the Batch service sets the Job to the terminating state. The Batch service then terminates any running Tasks associated with the Job and runs any required Job release Tasks. Then the Job moves into the completed state. If there are any Tasks in the Job in the active state, they will remain in the active state. Once a Job is terminated, new Tasks cannot be added and any remaining active Tasks will not be scheduled.
     *
     * @param jobId The ID of the Job to terminate.
     * @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> terminateAsync(String jobId, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(terminateWithServiceResponseAsync(jobId), serviceCallback);
    }

    /**
     * Terminates the specified Job, marking it as completed.
     * When a Terminate Job request is received, the Batch service sets the Job to the terminating state. The Batch service then terminates any running Tasks associated with the Job and runs any required Job release Tasks. Then the Job moves into the completed state. If there are any Tasks in the Job in the active state, they will remain in the active state. Once a Job is terminated, new Tasks cannot be added and any remaining active Tasks will not be scheduled.
     *
     * @param jobId The ID of the Job to terminate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> terminateAsync(String jobId) {
        return terminateWithServiceResponseAsync(jobId).map(new Func1<ServiceResponseWithHeaders<Void, JobTerminateHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, JobTerminateHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Terminates the specified Job, marking it as completed.
     * When a Terminate Job request is received, the Batch service sets the Job to the terminating state. The Batch service then terminates any running Tasks associated with the Job and runs any required Job release Tasks. Then the Job moves into the completed state. If there are any Tasks in the Job in the active state, they will remain in the active state. Once a Job is terminated, new Tasks cannot be added and any remaining active Tasks will not be scheduled.
     *
     * @param jobId The ID of the Job to terminate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, JobTerminateHeaders>> terminateWithServiceResponseAsync(String jobId) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (jobId == null) {
            throw new IllegalArgumentException("Parameter jobId 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 String terminateReason = null;
        final JobTerminateOptions jobTerminateOptions = null;
        Integer timeout = null;
        UUID clientRequestId = null;
        Boolean returnClientRequestId = null;
        DateTime ocpDate = null;
        String ifMatch = null;
        String ifNoneMatch = null;
        DateTime ifModifiedSince = null;
        DateTime ifUnmodifiedSince = null;
        JobTerminateParameter jobTerminateParameter = new JobTerminateParameter();
        jobTerminateParameter.withTerminateReason(null);
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        DateTimeRfc1123 ifModifiedSinceConverted = null;
        if (ifModifiedSince != null) {
            ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince);
        }
        DateTimeRfc1123 ifUnmodifiedSinceConverted = null;
        if (ifUnmodifiedSince != null) {
            ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince);
        }
        return service.terminate(jobId, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, ifMatch, ifNoneMatch, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, jobTerminateParameter, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, JobTerminateHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, JobTerminateHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, JobTerminateHeaders> clientResponse = terminateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Terminates the specified Job, marking it as completed.
     * When a Terminate Job request is received, the Batch service sets the Job to the terminating state. The Batch service then terminates any running Tasks associated with the Job and runs any required Job release Tasks. Then the Job moves into the completed state. If there are any Tasks in the Job in the active state, they will remain in the active state. Once a Job is terminated, new Tasks cannot be added and any remaining active Tasks will not be scheduled.
     *
     * @param jobId The ID of the Job to terminate.
     * @param terminateReason The text you want to appear as the Job's TerminateReason. The default is 'UserTerminate'.
     * @param jobTerminateOptions 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 terminate(String jobId, String terminateReason, JobTerminateOptions jobTerminateOptions) {
        terminateWithServiceResponseAsync(jobId, terminateReason, jobTerminateOptions).toBlocking().single().body();
    }

    /**
     * Terminates the specified Job, marking it as completed.
     * When a Terminate Job request is received, the Batch service sets the Job to the terminating state. The Batch service then terminates any running Tasks associated with the Job and runs any required Job release Tasks. Then the Job moves into the completed state. If there are any Tasks in the Job in the active state, they will remain in the active state. Once a Job is terminated, new Tasks cannot be added and any remaining active Tasks will not be scheduled.
     *
     * @param jobId The ID of the Job to terminate.
     * @param terminateReason The text you want to appear as the Job's TerminateReason. The default is 'UserTerminate'.
     * @param jobTerminateOptions 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> terminateAsync(String jobId, String terminateReason, JobTerminateOptions jobTerminateOptions, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(terminateWithServiceResponseAsync(jobId, terminateReason, jobTerminateOptions), serviceCallback);
    }

    /**
     * Terminates the specified Job, marking it as completed.
     * When a Terminate Job request is received, the Batch service sets the Job to the terminating state. The Batch service then terminates any running Tasks associated with the Job and runs any required Job release Tasks. Then the Job moves into the completed state. If there are any Tasks in the Job in the active state, they will remain in the active state. Once a Job is terminated, new Tasks cannot be added and any remaining active Tasks will not be scheduled.
     *
     * @param jobId The ID of the Job to terminate.
     * @param terminateReason The text you want to appear as the Job's TerminateReason. The default is 'UserTerminate'.
     * @param jobTerminateOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> terminateAsync(String jobId, String terminateReason, JobTerminateOptions jobTerminateOptions) {
        return terminateWithServiceResponseAsync(jobId, terminateReason, jobTerminateOptions).map(new Func1<ServiceResponseWithHeaders<Void, JobTerminateHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, JobTerminateHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Terminates the specified Job, marking it as completed.
     * When a Terminate Job request is received, the Batch service sets the Job to the terminating state. The Batch service then terminates any running Tasks associated with the Job and runs any required Job release Tasks. Then the Job moves into the completed state. If there are any Tasks in the Job in the active state, they will remain in the active state. Once a Job is terminated, new Tasks cannot be added and any remaining active Tasks will not be scheduled.
     *
     * @param jobId The ID of the Job to terminate.
     * @param terminateReason The text you want to appear as the Job's TerminateReason. The default is 'UserTerminate'.
     * @param jobTerminateOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, JobTerminateHeaders>> terminateWithServiceResponseAsync(String jobId, String terminateReason, JobTerminateOptions jobTerminateOptions) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (jobId == null) {
            throw new IllegalArgumentException("Parameter jobId 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(jobTerminateOptions);
        Integer timeout = null;
        if (jobTerminateOptions != null) {
            timeout = jobTerminateOptions.timeout();
        }
        UUID clientRequestId = null;
        if (jobTerminateOptions != null) {
            clientRequestId = jobTerminateOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (jobTerminateOptions != null) {
            returnClientRequestId = jobTerminateOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (jobTerminateOptions != null) {
            ocpDate = jobTerminateOptions.ocpDate();
        }
        String ifMatch = null;
        if (jobTerminateOptions != null) {
            ifMatch = jobTerminateOptions.ifMatch();
        }
        String ifNoneMatch = null;
        if (jobTerminateOptions != null) {
            ifNoneMatch = jobTerminateOptions.ifNoneMatch();
        }
        DateTime ifModifiedSince = null;
        if (jobTerminateOptions != null) {
            ifModifiedSince = jobTerminateOptions.ifModifiedSince();
        }
        DateTime ifUnmodifiedSince = null;
        if (jobTerminateOptions != null) {
            ifUnmodifiedSince = jobTerminateOptions.ifUnmodifiedSince();
        }
        JobTerminateParameter jobTerminateParameter = null;
        if (terminateReason != null) {
            jobTerminateParameter = new JobTerminateParameter();
            jobTerminateParameter.withTerminateReason(terminateReason);
        }
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        DateTimeRfc1123 ifModifiedSinceConverted = null;
        if (ifModifiedSince != null) {
            ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince);
        }
        DateTimeRfc1123 ifUnmodifiedSinceConverted = null;
        if (ifUnmodifiedSince != null) {
            ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince);
        }
        return service.terminate(jobId, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, ifMatch, ifNoneMatch, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, jobTerminateParameter, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, JobTerminateHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, JobTerminateHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, JobTerminateHeaders> clientResponse = terminateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponseWithHeaders<Void, JobTerminateHeaders> terminateDelegate(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, JobTerminateHeaders.class);
    }

    /**
     * Adds a Job to the specified Account.
     * The Batch service supports two ways to control the work done as part of a Job. In the first approach, the user specifies a Job Manager Task. The Batch service launches this Task when it is ready to start the Job. The Job Manager Task controls all other Tasks that run under this Job, by using the Task APIs. In the second approach, the user directly controls the execution of Tasks under an active Job, by using the Task APIs. Also note: when naming Jobs, avoid including sensitive information such as user names or secret project names. This information may appear in telemetry logs accessible to Microsoft Support engineers.
     *
     * @param job The Job 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(JobAddParameter job) {
        addWithServiceResponseAsync(job).toBlocking().single().body();
    }

    /**
     * Adds a Job to the specified Account.
     * The Batch service supports two ways to control the work done as part of a Job. In the first approach, the user specifies a Job Manager Task. The Batch service launches this Task when it is ready to start the Job. The Job Manager Task controls all other Tasks that run under this Job, by using the Task APIs. In the second approach, the user directly controls the execution of Tasks under an active Job, by using the Task APIs. Also note: when naming Jobs, avoid including sensitive information such as user names or secret project names. This information may appear in telemetry logs accessible to Microsoft Support engineers.
     *
     * @param job The Job 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(JobAddParameter job, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(addWithServiceResponseAsync(job), serviceCallback);
    }

    /**
     * Adds a Job to the specified Account.
     * The Batch service supports two ways to control the work done as part of a Job. In the first approach, the user specifies a Job Manager Task. The Batch service launches this Task when it is ready to start the Job. The Job Manager Task controls all other Tasks that run under this Job, by using the Task APIs. In the second approach, the user directly controls the execution of Tasks under an active Job, by using the Task APIs. Also note: when naming Jobs, avoid including sensitive information such as user names or secret project names. This information may appear in telemetry logs accessible to Microsoft Support engineers.
     *
     * @param job The Job to be added.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> addAsync(JobAddParameter job) {
        return addWithServiceResponseAsync(job).map(new Func1<ServiceResponseWithHeaders<Void, JobAddHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, JobAddHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Adds a Job to the specified Account.
     * The Batch service supports two ways to control the work done as part of a Job. In the first approach, the user specifies a Job Manager Task. The Batch service launches this Task when it is ready to start the Job. The Job Manager Task controls all other Tasks that run under this Job, by using the Task APIs. In the second approach, the user directly controls the execution of Tasks under an active Job, by using the Task APIs. Also note: when naming Jobs, avoid including sensitive information such as user names or secret project names. This information may appear in telemetry logs accessible to Microsoft Support engineers.
     *
     * @param job The Job to be added.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, JobAddHeaders>> addWithServiceResponseAsync(JobAddParameter job) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (job == null) {
            throw new IllegalArgumentException("Parameter job 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(job);
        final JobAddOptions jobAddOptions = 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(job, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, JobAddHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, JobAddHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, JobAddHeaders> clientResponse = addDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Adds a Job to the specified Account.
     * The Batch service supports two ways to control the work done as part of a Job. In the first approach, the user specifies a Job Manager Task. The Batch service launches this Task when it is ready to start the Job. The Job Manager Task controls all other Tasks that run under this Job, by using the Task APIs. In the second approach, the user directly controls the execution of Tasks under an active Job, by using the Task APIs. Also note: when naming Jobs, avoid including sensitive information such as user names or secret project names. This information may appear in telemetry logs accessible to Microsoft Support engineers.
     *
     * @param job The Job to be added.
     * @param jobAddOptions 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(JobAddParameter job, JobAddOptions jobAddOptions) {
        addWithServiceResponseAsync(job, jobAddOptions).toBlocking().single().body();
    }

    /**
     * Adds a Job to the specified Account.
     * The Batch service supports two ways to control the work done as part of a Job. In the first approach, the user specifies a Job Manager Task. The Batch service launches this Task when it is ready to start the Job. The Job Manager Task controls all other Tasks that run under this Job, by using the Task APIs. In the second approach, the user directly controls the execution of Tasks under an active Job, by using the Task APIs. Also note: when naming Jobs, avoid including sensitive information such as user names or secret project names. This information may appear in telemetry logs accessible to Microsoft Support engineers.
     *
     * @param job The Job to be added.
     * @param jobAddOptions 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(JobAddParameter job, JobAddOptions jobAddOptions, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(addWithServiceResponseAsync(job, jobAddOptions), serviceCallback);
    }

    /**
     * Adds a Job to the specified Account.
     * The Batch service supports two ways to control the work done as part of a Job. In the first approach, the user specifies a Job Manager Task. The Batch service launches this Task when it is ready to start the Job. The Job Manager Task controls all other Tasks that run under this Job, by using the Task APIs. In the second approach, the user directly controls the execution of Tasks under an active Job, by using the Task APIs. Also note: when naming Jobs, avoid including sensitive information such as user names or secret project names. This information may appear in telemetry logs accessible to Microsoft Support engineers.
     *
     * @param job The Job to be added.
     * @param jobAddOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> addAsync(JobAddParameter job, JobAddOptions jobAddOptions) {
        return addWithServiceResponseAsync(job, jobAddOptions).map(new Func1<ServiceResponseWithHeaders<Void, JobAddHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, JobAddHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Adds a Job to the specified Account.
     * The Batch service supports two ways to control the work done as part of a Job. In the first approach, the user specifies a Job Manager Task. The Batch service launches this Task when it is ready to start the Job. The Job Manager Task controls all other Tasks that run under this Job, by using the Task APIs. In the second approach, the user directly controls the execution of Tasks under an active Job, by using the Task APIs. Also note: when naming Jobs, avoid including sensitive information such as user names or secret project names. This information may appear in telemetry logs accessible to Microsoft Support engineers.
     *
     * @param job The Job to be added.
     * @param jobAddOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, JobAddHeaders>> addWithServiceResponseAsync(JobAddParameter job, JobAddOptions jobAddOptions) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (job == null) {
            throw new IllegalArgumentException("Parameter job 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(job);
        Validator.validate(jobAddOptions);
        Integer timeout = null;
        if (jobAddOptions != null) {
            timeout = jobAddOptions.timeout();
        }
        UUID clientRequestId = null;
        if (jobAddOptions != null) {
            clientRequestId = jobAddOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (jobAddOptions != null) {
            returnClientRequestId = jobAddOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (jobAddOptions != null) {
            ocpDate = jobAddOptions.ocpDate();
        }
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.add(job, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, JobAddHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, JobAddHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, JobAddHeaders> clientResponse = addDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponseWithHeaders<Void, JobAddHeaders> 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, JobAddHeaders.class);
    }

    /**
     * Lists all of the Jobs in the specified Account.
     *
     * @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;CloudJob&gt; object if successful.
     */
    public PagedList<CloudJob> list() {
        ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders> response = listSinglePageAsync().toBlocking().single();
        return new PagedList<CloudJob>(response.body()) {
            @Override
            public Page<CloudJob> nextPage(String nextPageLink) {
                return listNextSinglePageAsync(nextPageLink, null).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists all of the Jobs in the specified Account.
     *
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<CloudJob>> listAsync(final ListOperationCallback<CloudJob> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listSinglePageAsync(),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>> call(String nextPageLink) {
                    return listNextSinglePageAsync(nextPageLink, null);
                }
            },
            serviceCallback);
    }

    /**
     * Lists all of the Jobs in the specified Account.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CloudJob&gt; object
     */
    public Observable<Page<CloudJob>> listAsync() {
        return listWithServiceResponseAsync()
            .map(new Func1<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>, Page<CloudJob>>() {
                @Override
                public Page<CloudJob> call(ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists all of the Jobs in the specified Account.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CloudJob&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>> listWithServiceResponseAsync() {
        return listSinglePageAsync()
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>> call(ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders> 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 Jobs in the specified Account.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CloudJob&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>> 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 JobListOptions jobListOptions = null;
        String filter = null;
        String select = null;
        String expand = 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, expand, maxResults, timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<CloudJob>, JobListHeaders> result = listDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Lists all of the Jobs in the specified Account.
     *
     * @param jobListOptions 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;CloudJob&gt; object if successful.
     */
    public PagedList<CloudJob> list(final JobListOptions jobListOptions) {
        ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders> response = listSinglePageAsync(jobListOptions).toBlocking().single();
        return new PagedList<CloudJob>(response.body()) {
            @Override
            public Page<CloudJob> nextPage(String nextPageLink) {
                JobListNextOptions jobListNextOptions = null;
                if (jobListOptions != null) {
                    jobListNextOptions = new JobListNextOptions();
                    jobListNextOptions.withClientRequestId(jobListOptions.clientRequestId());
                    jobListNextOptions.withReturnClientRequestId(jobListOptions.returnClientRequestId());
                    jobListNextOptions.withOcpDate(jobListOptions.ocpDate());
                }
                return listNextSinglePageAsync(nextPageLink, jobListNextOptions).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists all of the Jobs in the specified Account.
     *
     * @param jobListOptions 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<CloudJob>> listAsync(final JobListOptions jobListOptions, final ListOperationCallback<CloudJob> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listSinglePageAsync(jobListOptions),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>> call(String nextPageLink) {
                    JobListNextOptions jobListNextOptions = null;
                    if (jobListOptions != null) {
                        jobListNextOptions = new JobListNextOptions();
                        jobListNextOptions.withClientRequestId(jobListOptions.clientRequestId());
                        jobListNextOptions.withReturnClientRequestId(jobListOptions.returnClientRequestId());
                        jobListNextOptions.withOcpDate(jobListOptions.ocpDate());
                    }
                    return listNextSinglePageAsync(nextPageLink, jobListNextOptions);
                }
            },
            serviceCallback);
    }

    /**
     * Lists all of the Jobs in the specified Account.
     *
     * @param jobListOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CloudJob&gt; object
     */
    public Observable<Page<CloudJob>> listAsync(final JobListOptions jobListOptions) {
        return listWithServiceResponseAsync(jobListOptions)
            .map(new Func1<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>, Page<CloudJob>>() {
                @Override
                public Page<CloudJob> call(ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists all of the Jobs in the specified Account.
     *
     * @param jobListOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CloudJob&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>> listWithServiceResponseAsync(final JobListOptions jobListOptions) {
        return listSinglePageAsync(jobListOptions)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>> call(ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    JobListNextOptions jobListNextOptions = null;
                    if (jobListOptions != null) {
                        jobListNextOptions = new JobListNextOptions();
                        jobListNextOptions.withClientRequestId(jobListOptions.clientRequestId());
                        jobListNextOptions.withReturnClientRequestId(jobListOptions.returnClientRequestId());
                        jobListNextOptions.withOcpDate(jobListOptions.ocpDate());
                    }
                    return Observable.just(page).concatWith(listNextWithServiceResponseAsync(nextPageLink, jobListNextOptions));
                }
            });
    }

    /**
     * Lists all of the Jobs in the specified Account.
     *
    ServiceResponseWithHeaders<PageImpl<CloudJob>, JobListHeaders> * @param jobListOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CloudJob&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>> listSinglePageAsync(final JobListOptions jobListOptions) {
        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(jobListOptions);
        String filter = null;
        if (jobListOptions != null) {
            filter = jobListOptions.filter();
        }
        String select = null;
        if (jobListOptions != null) {
            select = jobListOptions.select();
        }
        String expand = null;
        if (jobListOptions != null) {
            expand = jobListOptions.expand();
        }
        Integer maxResults = null;
        if (jobListOptions != null) {
            maxResults = jobListOptions.maxResults();
        }
        Integer timeout = null;
        if (jobListOptions != null) {
            timeout = jobListOptions.timeout();
        }
        UUID clientRequestId = null;
        if (jobListOptions != null) {
            clientRequestId = jobListOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (jobListOptions != null) {
            returnClientRequestId = jobListOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (jobListOptions != null) {
            ocpDate = jobListOptions.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, expand, maxResults, timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<CloudJob>, JobListHeaders> result = listDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Lists the Jobs that have been created under the specified Job Schedule.
     *
     * @param jobScheduleId The ID of the Job Schedule from which you want to get a list of Jobs.
     * @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;CloudJob&gt; object if successful.
     */
    public PagedList<CloudJob> listFromJobSchedule(final String jobScheduleId) {
        ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders> response = listFromJobScheduleSinglePageAsync(jobScheduleId).toBlocking().single();
        return new PagedList<CloudJob>(response.body()) {
            @Override
            public Page<CloudJob> nextPage(String nextPageLink) {
                return listFromJobScheduleNextSinglePageAsync(nextPageLink, null).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists the Jobs that have been created under the specified Job Schedule.
     *
     * @param jobScheduleId The ID of the Job Schedule from which you want to get a list of Jobs.
     * @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<CloudJob>> listFromJobScheduleAsync(final String jobScheduleId, final ListOperationCallback<CloudJob> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listFromJobScheduleSinglePageAsync(jobScheduleId),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>> call(String nextPageLink) {
                    return listFromJobScheduleNextSinglePageAsync(nextPageLink, null);
                }
            },
            serviceCallback);
    }

    /**
     * Lists the Jobs that have been created under the specified Job Schedule.
     *
     * @param jobScheduleId The ID of the Job Schedule from which you want to get a list of Jobs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CloudJob&gt; object
     */
    public Observable<Page<CloudJob>> listFromJobScheduleAsync(final String jobScheduleId) {
        return listFromJobScheduleWithServiceResponseAsync(jobScheduleId)
            .map(new Func1<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>, Page<CloudJob>>() {
                @Override
                public Page<CloudJob> call(ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists the Jobs that have been created under the specified Job Schedule.
     *
     * @param jobScheduleId The ID of the Job Schedule from which you want to get a list of Jobs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CloudJob&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>> listFromJobScheduleWithServiceResponseAsync(final String jobScheduleId) {
        return listFromJobScheduleSinglePageAsync(jobScheduleId)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>> call(ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listFromJobScheduleNextWithServiceResponseAsync(nextPageLink, null));
                }
            });
    }

    /**
     * Lists the Jobs that have been created under the specified Job Schedule.
     *
     * @param jobScheduleId The ID of the Job Schedule from which you want to get a list of Jobs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CloudJob&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>> listFromJobScheduleSinglePageAsync(final String jobScheduleId) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (jobScheduleId == null) {
            throw new IllegalArgumentException("Parameter jobScheduleId 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 JobListFromJobScheduleOptions jobListFromJobScheduleOptions = null;
        String filter = null;
        String select = null;
        String expand = 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.listFromJobSchedule(jobScheduleId, this.client.apiVersion(), this.client.acceptLanguage(), filter, select, expand, maxResults, timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<CloudJob>, JobListFromJobScheduleHeaders> result = listFromJobScheduleDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Lists the Jobs that have been created under the specified Job Schedule.
     *
     * @param jobScheduleId The ID of the Job Schedule from which you want to get a list of Jobs.
     * @param jobListFromJobScheduleOptions 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;CloudJob&gt; object if successful.
     */
    public PagedList<CloudJob> listFromJobSchedule(final String jobScheduleId, final JobListFromJobScheduleOptions jobListFromJobScheduleOptions) {
        ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders> response = listFromJobScheduleSinglePageAsync(jobScheduleId, jobListFromJobScheduleOptions).toBlocking().single();
        return new PagedList<CloudJob>(response.body()) {
            @Override
            public Page<CloudJob> nextPage(String nextPageLink) {
                JobListFromJobScheduleNextOptions jobListFromJobScheduleNextOptions = null;
                if (jobListFromJobScheduleOptions != null) {
                    jobListFromJobScheduleNextOptions = new JobListFromJobScheduleNextOptions();
                    jobListFromJobScheduleNextOptions.withClientRequestId(jobListFromJobScheduleOptions.clientRequestId());
                    jobListFromJobScheduleNextOptions.withReturnClientRequestId(jobListFromJobScheduleOptions.returnClientRequestId());
                    jobListFromJobScheduleNextOptions.withOcpDate(jobListFromJobScheduleOptions.ocpDate());
                }
                return listFromJobScheduleNextSinglePageAsync(nextPageLink, jobListFromJobScheduleNextOptions).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists the Jobs that have been created under the specified Job Schedule.
     *
     * @param jobScheduleId The ID of the Job Schedule from which you want to get a list of Jobs.
     * @param jobListFromJobScheduleOptions 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<CloudJob>> listFromJobScheduleAsync(final String jobScheduleId, final JobListFromJobScheduleOptions jobListFromJobScheduleOptions, final ListOperationCallback<CloudJob> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listFromJobScheduleSinglePageAsync(jobScheduleId, jobListFromJobScheduleOptions),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>> call(String nextPageLink) {
                    JobListFromJobScheduleNextOptions jobListFromJobScheduleNextOptions = null;
                    if (jobListFromJobScheduleOptions != null) {
                        jobListFromJobScheduleNextOptions = new JobListFromJobScheduleNextOptions();
                        jobListFromJobScheduleNextOptions.withClientRequestId(jobListFromJobScheduleOptions.clientRequestId());
                        jobListFromJobScheduleNextOptions.withReturnClientRequestId(jobListFromJobScheduleOptions.returnClientRequestId());
                        jobListFromJobScheduleNextOptions.withOcpDate(jobListFromJobScheduleOptions.ocpDate());
                    }
                    return listFromJobScheduleNextSinglePageAsync(nextPageLink, jobListFromJobScheduleNextOptions);
                }
            },
            serviceCallback);
    }

    /**
     * Lists the Jobs that have been created under the specified Job Schedule.
     *
     * @param jobScheduleId The ID of the Job Schedule from which you want to get a list of Jobs.
     * @param jobListFromJobScheduleOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CloudJob&gt; object
     */
    public Observable<Page<CloudJob>> listFromJobScheduleAsync(final String jobScheduleId, final JobListFromJobScheduleOptions jobListFromJobScheduleOptions) {
        return listFromJobScheduleWithServiceResponseAsync(jobScheduleId, jobListFromJobScheduleOptions)
            .map(new Func1<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>, Page<CloudJob>>() {
                @Override
                public Page<CloudJob> call(ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists the Jobs that have been created under the specified Job Schedule.
     *
     * @param jobScheduleId The ID of the Job Schedule from which you want to get a list of Jobs.
     * @param jobListFromJobScheduleOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CloudJob&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>> listFromJobScheduleWithServiceResponseAsync(final String jobScheduleId, final JobListFromJobScheduleOptions jobListFromJobScheduleOptions) {
        return listFromJobScheduleSinglePageAsync(jobScheduleId, jobListFromJobScheduleOptions)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>> call(ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    JobListFromJobScheduleNextOptions jobListFromJobScheduleNextOptions = null;
                    if (jobListFromJobScheduleOptions != null) {
                        jobListFromJobScheduleNextOptions = new JobListFromJobScheduleNextOptions();
                        jobListFromJobScheduleNextOptions.withClientRequestId(jobListFromJobScheduleOptions.clientRequestId());
                        jobListFromJobScheduleNextOptions.withReturnClientRequestId(jobListFromJobScheduleOptions.returnClientRequestId());
                        jobListFromJobScheduleNextOptions.withOcpDate(jobListFromJobScheduleOptions.ocpDate());
                    }
                    return Observable.just(page).concatWith(listFromJobScheduleNextWithServiceResponseAsync(nextPageLink, jobListFromJobScheduleNextOptions));
                }
            });
    }

    /**
     * Lists the Jobs that have been created under the specified Job Schedule.
     *
    ServiceResponseWithHeaders<PageImpl<CloudJob>, JobListFromJobScheduleHeaders> * @param jobScheduleId The ID of the Job Schedule from which you want to get a list of Jobs.
    ServiceResponseWithHeaders<PageImpl<CloudJob>, JobListFromJobScheduleHeaders> * @param jobListFromJobScheduleOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CloudJob&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>> listFromJobScheduleSinglePageAsync(final String jobScheduleId, final JobListFromJobScheduleOptions jobListFromJobScheduleOptions) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (jobScheduleId == null) {
            throw new IllegalArgumentException("Parameter jobScheduleId 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(jobListFromJobScheduleOptions);
        String filter = null;
        if (jobListFromJobScheduleOptions != null) {
            filter = jobListFromJobScheduleOptions.filter();
        }
        String select = null;
        if (jobListFromJobScheduleOptions != null) {
            select = jobListFromJobScheduleOptions.select();
        }
        String expand = null;
        if (jobListFromJobScheduleOptions != null) {
            expand = jobListFromJobScheduleOptions.expand();
        }
        Integer maxResults = null;
        if (jobListFromJobScheduleOptions != null) {
            maxResults = jobListFromJobScheduleOptions.maxResults();
        }
        Integer timeout = null;
        if (jobListFromJobScheduleOptions != null) {
            timeout = jobListFromJobScheduleOptions.timeout();
        }
        UUID clientRequestId = null;
        if (jobListFromJobScheduleOptions != null) {
            clientRequestId = jobListFromJobScheduleOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (jobListFromJobScheduleOptions != null) {
            returnClientRequestId = jobListFromJobScheduleOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (jobListFromJobScheduleOptions != null) {
            ocpDate = jobListFromJobScheduleOptions.ocpDate();
        }
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.listFromJobSchedule(jobScheduleId, this.client.apiVersion(), this.client.acceptLanguage(), filter, select, expand, maxResults, timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<CloudJob>, JobListFromJobScheduleHeaders> result = listFromJobScheduleDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Lists the execution status of the Job Preparation and Job Release Task for the specified Job across the Compute Nodes where the Job has run.
     * This API returns the Job Preparation and Job Release Task status on all Compute Nodes that have run the Job Preparation or Job Release Task. This includes Compute Nodes which have since been removed from the Pool. If this API is invoked on a Job which has no Job Preparation or Job Release Task, the Batch service returns HTTP status code 409 (Conflict) with an error code of JobPreparationTaskNotSpecified.
     *
     * @param jobId The ID of the Job.
     * @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;JobPreparationAndReleaseTaskExecutionInformation&gt; object if successful.
     */
    public PagedList<JobPreparationAndReleaseTaskExecutionInformation> listPreparationAndReleaseTaskStatus(final String jobId) {
        ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders> response = listPreparationAndReleaseTaskStatusSinglePageAsync(jobId).toBlocking().single();
        return new PagedList<JobPreparationAndReleaseTaskExecutionInformation>(response.body()) {
            @Override
            public Page<JobPreparationAndReleaseTaskExecutionInformation> nextPage(String nextPageLink) {
                return listPreparationAndReleaseTaskStatusNextSinglePageAsync(nextPageLink, null).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists the execution status of the Job Preparation and Job Release Task for the specified Job across the Compute Nodes where the Job has run.
     * This API returns the Job Preparation and Job Release Task status on all Compute Nodes that have run the Job Preparation or Job Release Task. This includes Compute Nodes which have since been removed from the Pool. If this API is invoked on a Job which has no Job Preparation or Job Release Task, the Batch service returns HTTP status code 409 (Conflict) with an error code of JobPreparationTaskNotSpecified.
     *
     * @param jobId The ID of the Job.
     * @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<JobPreparationAndReleaseTaskExecutionInformation>> listPreparationAndReleaseTaskStatusAsync(final String jobId, final ListOperationCallback<JobPreparationAndReleaseTaskExecutionInformation> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listPreparationAndReleaseTaskStatusSinglePageAsync(jobId),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>> call(String nextPageLink) {
                    return listPreparationAndReleaseTaskStatusNextSinglePageAsync(nextPageLink, null);
                }
            },
            serviceCallback);
    }

    /**
     * Lists the execution status of the Job Preparation and Job Release Task for the specified Job across the Compute Nodes where the Job has run.
     * This API returns the Job Preparation and Job Release Task status on all Compute Nodes that have run the Job Preparation or Job Release Task. This includes Compute Nodes which have since been removed from the Pool. If this API is invoked on a Job which has no Job Preparation or Job Release Task, the Batch service returns HTTP status code 409 (Conflict) with an error code of JobPreparationTaskNotSpecified.
     *
     * @param jobId The ID of the Job.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;JobPreparationAndReleaseTaskExecutionInformation&gt; object
     */
    public Observable<Page<JobPreparationAndReleaseTaskExecutionInformation>> listPreparationAndReleaseTaskStatusAsync(final String jobId) {
        return listPreparationAndReleaseTaskStatusWithServiceResponseAsync(jobId)
            .map(new Func1<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>, Page<JobPreparationAndReleaseTaskExecutionInformation>>() {
                @Override
                public Page<JobPreparationAndReleaseTaskExecutionInformation> call(ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists the execution status of the Job Preparation and Job Release Task for the specified Job across the Compute Nodes where the Job has run.
     * This API returns the Job Preparation and Job Release Task status on all Compute Nodes that have run the Job Preparation or Job Release Task. This includes Compute Nodes which have since been removed from the Pool. If this API is invoked on a Job which has no Job Preparation or Job Release Task, the Batch service returns HTTP status code 409 (Conflict) with an error code of JobPreparationTaskNotSpecified.
     *
     * @param jobId The ID of the Job.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;JobPreparationAndReleaseTaskExecutionInformation&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>> listPreparationAndReleaseTaskStatusWithServiceResponseAsync(final String jobId) {
        return listPreparationAndReleaseTaskStatusSinglePageAsync(jobId)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>, Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>> call(ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listPreparationAndReleaseTaskStatusNextWithServiceResponseAsync(nextPageLink, null));
                }
            });
    }

    /**
     * Lists the execution status of the Job Preparation and Job Release Task for the specified Job across the Compute Nodes where the Job has run.
     * This API returns the Job Preparation and Job Release Task status on all Compute Nodes that have run the Job Preparation or Job Release Task. This includes Compute Nodes which have since been removed from the Pool. If this API is invoked on a Job which has no Job Preparation or Job Release Task, the Batch service returns HTTP status code 409 (Conflict) with an error code of JobPreparationTaskNotSpecified.
     *
     * @param jobId The ID of the Job.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;JobPreparationAndReleaseTaskExecutionInformation&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>> listPreparationAndReleaseTaskStatusSinglePageAsync(final String jobId) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (jobId == null) {
            throw new IllegalArgumentException("Parameter jobId 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 JobListPreparationAndReleaseTaskStatusOptions jobListPreparationAndReleaseTaskStatusOptions = 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.listPreparationAndReleaseTaskStatus(jobId, 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<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders> result = listPreparationAndReleaseTaskStatusDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Lists the execution status of the Job Preparation and Job Release Task for the specified Job across the Compute Nodes where the Job has run.
     * This API returns the Job Preparation and Job Release Task status on all Compute Nodes that have run the Job Preparation or Job Release Task. This includes Compute Nodes which have since been removed from the Pool. If this API is invoked on a Job which has no Job Preparation or Job Release Task, the Batch service returns HTTP status code 409 (Conflict) with an error code of JobPreparationTaskNotSpecified.
     *
     * @param jobId The ID of the Job.
     * @param jobListPreparationAndReleaseTaskStatusOptions 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;JobPreparationAndReleaseTaskExecutionInformation&gt; object if successful.
     */
    public PagedList<JobPreparationAndReleaseTaskExecutionInformation> listPreparationAndReleaseTaskStatus(final String jobId, final JobListPreparationAndReleaseTaskStatusOptions jobListPreparationAndReleaseTaskStatusOptions) {
        ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders> response = listPreparationAndReleaseTaskStatusSinglePageAsync(jobId, jobListPreparationAndReleaseTaskStatusOptions).toBlocking().single();
        return new PagedList<JobPreparationAndReleaseTaskExecutionInformation>(response.body()) {
            @Override
            public Page<JobPreparationAndReleaseTaskExecutionInformation> nextPage(String nextPageLink) {
                JobListPreparationAndReleaseTaskStatusNextOptions jobListPreparationAndReleaseTaskStatusNextOptions = null;
                if (jobListPreparationAndReleaseTaskStatusOptions != null) {
                    jobListPreparationAndReleaseTaskStatusNextOptions = new JobListPreparationAndReleaseTaskStatusNextOptions();
                    jobListPreparationAndReleaseTaskStatusNextOptions.withClientRequestId(jobListPreparationAndReleaseTaskStatusOptions.clientRequestId());
                    jobListPreparationAndReleaseTaskStatusNextOptions.withReturnClientRequestId(jobListPreparationAndReleaseTaskStatusOptions.returnClientRequestId());
                    jobListPreparationAndReleaseTaskStatusNextOptions.withOcpDate(jobListPreparationAndReleaseTaskStatusOptions.ocpDate());
                }
                return listPreparationAndReleaseTaskStatusNextSinglePageAsync(nextPageLink, jobListPreparationAndReleaseTaskStatusNextOptions).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists the execution status of the Job Preparation and Job Release Task for the specified Job across the Compute Nodes where the Job has run.
     * This API returns the Job Preparation and Job Release Task status on all Compute Nodes that have run the Job Preparation or Job Release Task. This includes Compute Nodes which have since been removed from the Pool. If this API is invoked on a Job which has no Job Preparation or Job Release Task, the Batch service returns HTTP status code 409 (Conflict) with an error code of JobPreparationTaskNotSpecified.
     *
     * @param jobId The ID of the Job.
     * @param jobListPreparationAndReleaseTaskStatusOptions 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<JobPreparationAndReleaseTaskExecutionInformation>> listPreparationAndReleaseTaskStatusAsync(final String jobId, final JobListPreparationAndReleaseTaskStatusOptions jobListPreparationAndReleaseTaskStatusOptions, final ListOperationCallback<JobPreparationAndReleaseTaskExecutionInformation> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listPreparationAndReleaseTaskStatusSinglePageAsync(jobId, jobListPreparationAndReleaseTaskStatusOptions),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>> call(String nextPageLink) {
                    JobListPreparationAndReleaseTaskStatusNextOptions jobListPreparationAndReleaseTaskStatusNextOptions = null;
                    if (jobListPreparationAndReleaseTaskStatusOptions != null) {
                        jobListPreparationAndReleaseTaskStatusNextOptions = new JobListPreparationAndReleaseTaskStatusNextOptions();
                        jobListPreparationAndReleaseTaskStatusNextOptions.withClientRequestId(jobListPreparationAndReleaseTaskStatusOptions.clientRequestId());
                        jobListPreparationAndReleaseTaskStatusNextOptions.withReturnClientRequestId(jobListPreparationAndReleaseTaskStatusOptions.returnClientRequestId());
                        jobListPreparationAndReleaseTaskStatusNextOptions.withOcpDate(jobListPreparationAndReleaseTaskStatusOptions.ocpDate());
                    }
                    return listPreparationAndReleaseTaskStatusNextSinglePageAsync(nextPageLink, jobListPreparationAndReleaseTaskStatusNextOptions);
                }
            },
            serviceCallback);
    }

    /**
     * Lists the execution status of the Job Preparation and Job Release Task for the specified Job across the Compute Nodes where the Job has run.
     * This API returns the Job Preparation and Job Release Task status on all Compute Nodes that have run the Job Preparation or Job Release Task. This includes Compute Nodes which have since been removed from the Pool. If this API is invoked on a Job which has no Job Preparation or Job Release Task, the Batch service returns HTTP status code 409 (Conflict) with an error code of JobPreparationTaskNotSpecified.
     *
     * @param jobId The ID of the Job.
     * @param jobListPreparationAndReleaseTaskStatusOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;JobPreparationAndReleaseTaskExecutionInformation&gt; object
     */
    public Observable<Page<JobPreparationAndReleaseTaskExecutionInformation>> listPreparationAndReleaseTaskStatusAsync(final String jobId, final JobListPreparationAndReleaseTaskStatusOptions jobListPreparationAndReleaseTaskStatusOptions) {
        return listPreparationAndReleaseTaskStatusWithServiceResponseAsync(jobId, jobListPreparationAndReleaseTaskStatusOptions)
            .map(new Func1<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>, Page<JobPreparationAndReleaseTaskExecutionInformation>>() {
                @Override
                public Page<JobPreparationAndReleaseTaskExecutionInformation> call(ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists the execution status of the Job Preparation and Job Release Task for the specified Job across the Compute Nodes where the Job has run.
     * This API returns the Job Preparation and Job Release Task status on all Compute Nodes that have run the Job Preparation or Job Release Task. This includes Compute Nodes which have since been removed from the Pool. If this API is invoked on a Job which has no Job Preparation or Job Release Task, the Batch service returns HTTP status code 409 (Conflict) with an error code of JobPreparationTaskNotSpecified.
     *
     * @param jobId The ID of the Job.
     * @param jobListPreparationAndReleaseTaskStatusOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;JobPreparationAndReleaseTaskExecutionInformation&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>> listPreparationAndReleaseTaskStatusWithServiceResponseAsync(final String jobId, final JobListPreparationAndReleaseTaskStatusOptions jobListPreparationAndReleaseTaskStatusOptions) {
        return listPreparationAndReleaseTaskStatusSinglePageAsync(jobId, jobListPreparationAndReleaseTaskStatusOptions)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>, Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>> call(ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    JobListPreparationAndReleaseTaskStatusNextOptions jobListPreparationAndReleaseTaskStatusNextOptions = null;
                    if (jobListPreparationAndReleaseTaskStatusOptions != null) {
                        jobListPreparationAndReleaseTaskStatusNextOptions = new JobListPreparationAndReleaseTaskStatusNextOptions();
                        jobListPreparationAndReleaseTaskStatusNextOptions.withClientRequestId(jobListPreparationAndReleaseTaskStatusOptions.clientRequestId());
                        jobListPreparationAndReleaseTaskStatusNextOptions.withReturnClientRequestId(jobListPreparationAndReleaseTaskStatusOptions.returnClientRequestId());
                        jobListPreparationAndReleaseTaskStatusNextOptions.withOcpDate(jobListPreparationAndReleaseTaskStatusOptions.ocpDate());
                    }
                    return Observable.just(page).concatWith(listPreparationAndReleaseTaskStatusNextWithServiceResponseAsync(nextPageLink, jobListPreparationAndReleaseTaskStatusNextOptions));
                }
            });
    }

    /**
     * Lists the execution status of the Job Preparation and Job Release Task for the specified Job across the Compute Nodes where the Job has run.
     * This API returns the Job Preparation and Job Release Task status on all Compute Nodes that have run the Job Preparation or Job Release Task. This includes Compute Nodes which have since been removed from the Pool. If this API is invoked on a Job which has no Job Preparation or Job Release Task, the Batch service returns HTTP status code 409 (Conflict) with an error code of JobPreparationTaskNotSpecified.
     *
    ServiceResponseWithHeaders<PageImpl<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders> * @param jobId The ID of the Job.
    ServiceResponseWithHeaders<PageImpl<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders> * @param jobListPreparationAndReleaseTaskStatusOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;JobPreparationAndReleaseTaskExecutionInformation&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>> listPreparationAndReleaseTaskStatusSinglePageAsync(final String jobId, final JobListPreparationAndReleaseTaskStatusOptions jobListPreparationAndReleaseTaskStatusOptions) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (jobId == null) {
            throw new IllegalArgumentException("Parameter jobId 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(jobListPreparationAndReleaseTaskStatusOptions);
        String filter = null;
        if (jobListPreparationAndReleaseTaskStatusOptions != null) {
            filter = jobListPreparationAndReleaseTaskStatusOptions.filter();
        }
        String select = null;
        if (jobListPreparationAndReleaseTaskStatusOptions != null) {
            select = jobListPreparationAndReleaseTaskStatusOptions.select();
        }
        Integer maxResults = null;
        if (jobListPreparationAndReleaseTaskStatusOptions != null) {
            maxResults = jobListPreparationAndReleaseTaskStatusOptions.maxResults();
        }
        Integer timeout = null;
        if (jobListPreparationAndReleaseTaskStatusOptions != null) {
            timeout = jobListPreparationAndReleaseTaskStatusOptions.timeout();
        }
        UUID clientRequestId = null;
        if (jobListPreparationAndReleaseTaskStatusOptions != null) {
            clientRequestId = jobListPreparationAndReleaseTaskStatusOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (jobListPreparationAndReleaseTaskStatusOptions != null) {
            returnClientRequestId = jobListPreparationAndReleaseTaskStatusOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (jobListPreparationAndReleaseTaskStatusOptions != null) {
            ocpDate = jobListPreparationAndReleaseTaskStatusOptions.ocpDate();
        }
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.listPreparationAndReleaseTaskStatus(jobId, 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<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders> result = listPreparationAndReleaseTaskStatusDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Gets the Task counts for the specified Job.
     * Task counts provide a count of the Tasks by active, running or completed Task state, and a count of Tasks which succeeded or failed. Tasks in the preparing state are counted as running. Note that the numbers returned may not always be up to date. If you need exact task counts, use a list query.
     *
     * @param jobId The ID of the Job.
     * @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 TaskCountsResult object if successful.
     */
    public TaskCountsResult getTaskCounts(String jobId) {
        return getTaskCountsWithServiceResponseAsync(jobId).toBlocking().single().body();
    }

    /**
     * Gets the Task counts for the specified Job.
     * Task counts provide a count of the Tasks by active, running or completed Task state, and a count of Tasks which succeeded or failed. Tasks in the preparing state are counted as running. Note that the numbers returned may not always be up to date. If you need exact task counts, use a list query.
     *
     * @param jobId The ID of the Job.
     * @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<TaskCountsResult> getTaskCountsAsync(String jobId, final ServiceCallback<TaskCountsResult> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(getTaskCountsWithServiceResponseAsync(jobId), serviceCallback);
    }

    /**
     * Gets the Task counts for the specified Job.
     * Task counts provide a count of the Tasks by active, running or completed Task state, and a count of Tasks which succeeded or failed. Tasks in the preparing state are counted as running. Note that the numbers returned may not always be up to date. If you need exact task counts, use a list query.
     *
     * @param jobId The ID of the Job.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the TaskCountsResult object
     */
    public Observable<TaskCountsResult> getTaskCountsAsync(String jobId) {
        return getTaskCountsWithServiceResponseAsync(jobId).map(new Func1<ServiceResponseWithHeaders<TaskCountsResult, JobGetTaskCountsHeaders>, TaskCountsResult>() {
            @Override
            public TaskCountsResult call(ServiceResponseWithHeaders<TaskCountsResult, JobGetTaskCountsHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets the Task counts for the specified Job.
     * Task counts provide a count of the Tasks by active, running or completed Task state, and a count of Tasks which succeeded or failed. Tasks in the preparing state are counted as running. Note that the numbers returned may not always be up to date. If you need exact task counts, use a list query.
     *
     * @param jobId The ID of the Job.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the TaskCountsResult object
     */
    public Observable<ServiceResponseWithHeaders<TaskCountsResult, JobGetTaskCountsHeaders>> getTaskCountsWithServiceResponseAsync(String jobId) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (jobId == null) {
            throw new IllegalArgumentException("Parameter jobId 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 JobGetTaskCountsOptions jobGetTaskCountsOptions = 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.getTaskCounts(jobId, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<TaskCountsResult, JobGetTaskCountsHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<TaskCountsResult, JobGetTaskCountsHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<TaskCountsResult, JobGetTaskCountsHeaders> clientResponse = getTaskCountsDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Gets the Task counts for the specified Job.
     * Task counts provide a count of the Tasks by active, running or completed Task state, and a count of Tasks which succeeded or failed. Tasks in the preparing state are counted as running. Note that the numbers returned may not always be up to date. If you need exact task counts, use a list query.
     *
     * @param jobId The ID of the Job.
     * @param jobGetTaskCountsOptions 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 TaskCountsResult object if successful.
     */
    public TaskCountsResult getTaskCounts(String jobId, JobGetTaskCountsOptions jobGetTaskCountsOptions) {
        return getTaskCountsWithServiceResponseAsync(jobId, jobGetTaskCountsOptions).toBlocking().single().body();
    }

    /**
     * Gets the Task counts for the specified Job.
     * Task counts provide a count of the Tasks by active, running or completed Task state, and a count of Tasks which succeeded or failed. Tasks in the preparing state are counted as running. Note that the numbers returned may not always be up to date. If you need exact task counts, use a list query.
     *
     * @param jobId The ID of the Job.
     * @param jobGetTaskCountsOptions 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<TaskCountsResult> getTaskCountsAsync(String jobId, JobGetTaskCountsOptions jobGetTaskCountsOptions, final ServiceCallback<TaskCountsResult> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(getTaskCountsWithServiceResponseAsync(jobId, jobGetTaskCountsOptions), serviceCallback);
    }

    /**
     * Gets the Task counts for the specified Job.
     * Task counts provide a count of the Tasks by active, running or completed Task state, and a count of Tasks which succeeded or failed. Tasks in the preparing state are counted as running. Note that the numbers returned may not always be up to date. If you need exact task counts, use a list query.
     *
     * @param jobId The ID of the Job.
     * @param jobGetTaskCountsOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the TaskCountsResult object
     */
    public Observable<TaskCountsResult> getTaskCountsAsync(String jobId, JobGetTaskCountsOptions jobGetTaskCountsOptions) {
        return getTaskCountsWithServiceResponseAsync(jobId, jobGetTaskCountsOptions).map(new Func1<ServiceResponseWithHeaders<TaskCountsResult, JobGetTaskCountsHeaders>, TaskCountsResult>() {
            @Override
            public TaskCountsResult call(ServiceResponseWithHeaders<TaskCountsResult, JobGetTaskCountsHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets the Task counts for the specified Job.
     * Task counts provide a count of the Tasks by active, running or completed Task state, and a count of Tasks which succeeded or failed. Tasks in the preparing state are counted as running. Note that the numbers returned may not always be up to date. If you need exact task counts, use a list query.
     *
     * @param jobId The ID of the Job.
     * @param jobGetTaskCountsOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the TaskCountsResult object
     */
    public Observable<ServiceResponseWithHeaders<TaskCountsResult, JobGetTaskCountsHeaders>> getTaskCountsWithServiceResponseAsync(String jobId, JobGetTaskCountsOptions jobGetTaskCountsOptions) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (jobId == null) {
            throw new IllegalArgumentException("Parameter jobId 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(jobGetTaskCountsOptions);
        Integer timeout = null;
        if (jobGetTaskCountsOptions != null) {
            timeout = jobGetTaskCountsOptions.timeout();
        }
        UUID clientRequestId = null;
        if (jobGetTaskCountsOptions != null) {
            clientRequestId = jobGetTaskCountsOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (jobGetTaskCountsOptions != null) {
            returnClientRequestId = jobGetTaskCountsOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (jobGetTaskCountsOptions != null) {
            ocpDate = jobGetTaskCountsOptions.ocpDate();
        }
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.getTaskCounts(jobId, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<TaskCountsResult, JobGetTaskCountsHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<TaskCountsResult, JobGetTaskCountsHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<TaskCountsResult, JobGetTaskCountsHeaders> clientResponse = getTaskCountsDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Lists all of the Jobs in the specified Account.
     *
     * @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;CloudJob&gt; object if successful.
     */
    public PagedList<CloudJob> listNext(final String nextPageLink) {
        ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders> response = listNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<CloudJob>(response.body()) {
            @Override
            public Page<CloudJob> nextPage(String nextPageLink) {
                return listNextSinglePageAsync(nextPageLink, null).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists all of the Jobs in the specified Account.
     *
     * @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<CloudJob>> listNextAsync(final String nextPageLink, final ServiceFuture<List<CloudJob>> serviceFuture, final ListOperationCallback<CloudJob> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>> call(String nextPageLink) {
                    return listNextSinglePageAsync(nextPageLink, null);
                }
            },
            serviceCallback);
    }

    /**
     * Lists all of the Jobs in the specified Account.
     *
     * @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;CloudJob&gt; object
     */
    public Observable<Page<CloudJob>> listNextAsync(final String nextPageLink) {
        return listNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>, Page<CloudJob>>() {
                @Override
                public Page<CloudJob> call(ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists all of the Jobs in the specified Account.
     *
     * @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;CloudJob&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>> listNextWithServiceResponseAsync(final String nextPageLink) {
        return listNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>> call(ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders> 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 Jobs in the specified Account.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CloudJob&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>> listNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        final JobListNextOptions jobListNextOptions = 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<CloudJob>, JobListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<CloudJob>, JobListHeaders> result = listNextDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Lists all of the Jobs in the specified Account.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param jobListNextOptions 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;CloudJob&gt; object if successful.
     */
    public PagedList<CloudJob> listNext(final String nextPageLink, final JobListNextOptions jobListNextOptions) {
        ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders> response = listNextSinglePageAsync(nextPageLink, jobListNextOptions).toBlocking().single();
        return new PagedList<CloudJob>(response.body()) {
            @Override
            public Page<CloudJob> nextPage(String nextPageLink) {
                return listNextSinglePageAsync(nextPageLink, jobListNextOptions).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists all of the Jobs in the specified Account.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param jobListNextOptions 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<CloudJob>> listNextAsync(final String nextPageLink, final JobListNextOptions jobListNextOptions, final ServiceFuture<List<CloudJob>> serviceFuture, final ListOperationCallback<CloudJob> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listNextSinglePageAsync(nextPageLink, jobListNextOptions),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>> call(String nextPageLink) {
                    return listNextSinglePageAsync(nextPageLink, jobListNextOptions);
                }
            },
            serviceCallback);
    }

    /**
     * Lists all of the Jobs in the specified Account.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param jobListNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CloudJob&gt; object
     */
    public Observable<Page<CloudJob>> listNextAsync(final String nextPageLink, final JobListNextOptions jobListNextOptions) {
        return listNextWithServiceResponseAsync(nextPageLink, jobListNextOptions)
            .map(new Func1<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>, Page<CloudJob>>() {
                @Override
                public Page<CloudJob> call(ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists all of the Jobs in the specified Account.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param jobListNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CloudJob&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>> listNextWithServiceResponseAsync(final String nextPageLink, final JobListNextOptions jobListNextOptions) {
        return listNextSinglePageAsync(nextPageLink, jobListNextOptions)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>> call(ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listNextWithServiceResponseAsync(nextPageLink, jobListNextOptions));
                }
            });
    }

    /**
     * Lists all of the Jobs in the specified Account.
     *
    ServiceResponseWithHeaders<PageImpl<CloudJob>, JobListHeaders> * @param nextPageLink The NextLink from the previous successful call to List operation.
    ServiceResponseWithHeaders<PageImpl<CloudJob>, JobListHeaders> * @param jobListNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CloudJob&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>> listNextSinglePageAsync(final String nextPageLink, final JobListNextOptions jobListNextOptions) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        Validator.validate(jobListNextOptions);
        UUID clientRequestId = null;
        if (jobListNextOptions != null) {
            clientRequestId = jobListNextOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (jobListNextOptions != null) {
            returnClientRequestId = jobListNextOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (jobListNextOptions != null) {
            ocpDate = jobListNextOptions.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<CloudJob>, JobListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<CloudJob>, JobListHeaders> result = listNextDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<CloudJob>, JobListHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Lists the Jobs that have been created under the specified Job Schedule.
     *
     * @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;CloudJob&gt; object if successful.
     */
    public PagedList<CloudJob> listFromJobScheduleNext(final String nextPageLink) {
        ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders> response = listFromJobScheduleNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<CloudJob>(response.body()) {
            @Override
            public Page<CloudJob> nextPage(String nextPageLink) {
                return listFromJobScheduleNextSinglePageAsync(nextPageLink, null).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists the Jobs that have been created under the specified Job Schedule.
     *
     * @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<CloudJob>> listFromJobScheduleNextAsync(final String nextPageLink, final ServiceFuture<List<CloudJob>> serviceFuture, final ListOperationCallback<CloudJob> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listFromJobScheduleNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>> call(String nextPageLink) {
                    return listFromJobScheduleNextSinglePageAsync(nextPageLink, null);
                }
            },
            serviceCallback);
    }

    /**
     * Lists the Jobs that have been created under the specified Job Schedule.
     *
     * @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;CloudJob&gt; object
     */
    public Observable<Page<CloudJob>> listFromJobScheduleNextAsync(final String nextPageLink) {
        return listFromJobScheduleNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>, Page<CloudJob>>() {
                @Override
                public Page<CloudJob> call(ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists the Jobs that have been created under the specified Job Schedule.
     *
     * @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;CloudJob&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>> listFromJobScheduleNextWithServiceResponseAsync(final String nextPageLink) {
        return listFromJobScheduleNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>> call(ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listFromJobScheduleNextWithServiceResponseAsync(nextPageLink, null));
                }
            });
    }

    /**
     * Lists the Jobs that have been created under the specified Job Schedule.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CloudJob&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>> listFromJobScheduleNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        final JobListFromJobScheduleNextOptions jobListFromJobScheduleNextOptions = 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.listFromJobScheduleNext(nextUrl, this.client.acceptLanguage(), clientRequestId, returnClientRequestId, ocpDateConverted, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<CloudJob>, JobListFromJobScheduleHeaders> result = listFromJobScheduleNextDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Lists the Jobs that have been created under the specified Job Schedule.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param jobListFromJobScheduleNextOptions 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;CloudJob&gt; object if successful.
     */
    public PagedList<CloudJob> listFromJobScheduleNext(final String nextPageLink, final JobListFromJobScheduleNextOptions jobListFromJobScheduleNextOptions) {
        ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders> response = listFromJobScheduleNextSinglePageAsync(nextPageLink, jobListFromJobScheduleNextOptions).toBlocking().single();
        return new PagedList<CloudJob>(response.body()) {
            @Override
            public Page<CloudJob> nextPage(String nextPageLink) {
                return listFromJobScheduleNextSinglePageAsync(nextPageLink, jobListFromJobScheduleNextOptions).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists the Jobs that have been created under the specified Job Schedule.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param jobListFromJobScheduleNextOptions 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<CloudJob>> listFromJobScheduleNextAsync(final String nextPageLink, final JobListFromJobScheduleNextOptions jobListFromJobScheduleNextOptions, final ServiceFuture<List<CloudJob>> serviceFuture, final ListOperationCallback<CloudJob> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listFromJobScheduleNextSinglePageAsync(nextPageLink, jobListFromJobScheduleNextOptions),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>> call(String nextPageLink) {
                    return listFromJobScheduleNextSinglePageAsync(nextPageLink, jobListFromJobScheduleNextOptions);
                }
            },
            serviceCallback);
    }

    /**
     * Lists the Jobs that have been created under the specified Job Schedule.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param jobListFromJobScheduleNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CloudJob&gt; object
     */
    public Observable<Page<CloudJob>> listFromJobScheduleNextAsync(final String nextPageLink, final JobListFromJobScheduleNextOptions jobListFromJobScheduleNextOptions) {
        return listFromJobScheduleNextWithServiceResponseAsync(nextPageLink, jobListFromJobScheduleNextOptions)
            .map(new Func1<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>, Page<CloudJob>>() {
                @Override
                public Page<CloudJob> call(ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists the Jobs that have been created under the specified Job Schedule.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param jobListFromJobScheduleNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CloudJob&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>> listFromJobScheduleNextWithServiceResponseAsync(final String nextPageLink, final JobListFromJobScheduleNextOptions jobListFromJobScheduleNextOptions) {
        return listFromJobScheduleNextSinglePageAsync(nextPageLink, jobListFromJobScheduleNextOptions)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>> call(ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listFromJobScheduleNextWithServiceResponseAsync(nextPageLink, jobListFromJobScheduleNextOptions));
                }
            });
    }

    /**
     * Lists the Jobs that have been created under the specified Job Schedule.
     *
    ServiceResponseWithHeaders<PageImpl<CloudJob>, JobListFromJobScheduleHeaders> * @param nextPageLink The NextLink from the previous successful call to List operation.
    ServiceResponseWithHeaders<PageImpl<CloudJob>, JobListFromJobScheduleHeaders> * @param jobListFromJobScheduleNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CloudJob&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>> listFromJobScheduleNextSinglePageAsync(final String nextPageLink, final JobListFromJobScheduleNextOptions jobListFromJobScheduleNextOptions) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        Validator.validate(jobListFromJobScheduleNextOptions);
        UUID clientRequestId = null;
        if (jobListFromJobScheduleNextOptions != null) {
            clientRequestId = jobListFromJobScheduleNextOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (jobListFromJobScheduleNextOptions != null) {
            returnClientRequestId = jobListFromJobScheduleNextOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (jobListFromJobScheduleNextOptions != null) {
            ocpDate = jobListFromJobScheduleNextOptions.ocpDate();
        }
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.listFromJobScheduleNext(nextUrl, this.client.acceptLanguage(), clientRequestId, returnClientRequestId, ocpDateConverted, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<CloudJob>, JobListFromJobScheduleHeaders> result = listFromJobScheduleNextDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<CloudJob>, JobListFromJobScheduleHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Lists the execution status of the Job Preparation and Job Release Task for the specified Job across the Compute Nodes where the Job has run.
     * This API returns the Job Preparation and Job Release Task status on all Compute Nodes that have run the Job Preparation or Job Release Task. This includes Compute Nodes which have since been removed from the Pool. If this API is invoked on a Job which has no Job Preparation or Job Release Task, the Batch service returns HTTP status code 409 (Conflict) with an error code of JobPreparationTaskNotSpecified.
     *
     * @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;JobPreparationAndReleaseTaskExecutionInformation&gt; object if successful.
     */
    public PagedList<JobPreparationAndReleaseTaskExecutionInformation> listPreparationAndReleaseTaskStatusNext(final String nextPageLink) {
        ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders> response = listPreparationAndReleaseTaskStatusNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<JobPreparationAndReleaseTaskExecutionInformation>(response.body()) {
            @Override
            public Page<JobPreparationAndReleaseTaskExecutionInformation> nextPage(String nextPageLink) {
                return listPreparationAndReleaseTaskStatusNextSinglePageAsync(nextPageLink, null).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists the execution status of the Job Preparation and Job Release Task for the specified Job across the Compute Nodes where the Job has run.
     * This API returns the Job Preparation and Job Release Task status on all Compute Nodes that have run the Job Preparation or Job Release Task. This includes Compute Nodes which have since been removed from the Pool. If this API is invoked on a Job which has no Job Preparation or Job Release Task, the Batch service returns HTTP status code 409 (Conflict) with an error code of JobPreparationTaskNotSpecified.
     *
     * @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<JobPreparationAndReleaseTaskExecutionInformation>> listPreparationAndReleaseTaskStatusNextAsync(final String nextPageLink, final ServiceFuture<List<JobPreparationAndReleaseTaskExecutionInformation>> serviceFuture, final ListOperationCallback<JobPreparationAndReleaseTaskExecutionInformation> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listPreparationAndReleaseTaskStatusNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>> call(String nextPageLink) {
                    return listPreparationAndReleaseTaskStatusNextSinglePageAsync(nextPageLink, null);
                }
            },
            serviceCallback);
    }

    /**
     * Lists the execution status of the Job Preparation and Job Release Task for the specified Job across the Compute Nodes where the Job has run.
     * This API returns the Job Preparation and Job Release Task status on all Compute Nodes that have run the Job Preparation or Job Release Task. This includes Compute Nodes which have since been removed from the Pool. If this API is invoked on a Job which has no Job Preparation or Job Release Task, the Batch service returns HTTP status code 409 (Conflict) with an error code of JobPreparationTaskNotSpecified.
     *
     * @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;JobPreparationAndReleaseTaskExecutionInformation&gt; object
     */
    public Observable<Page<JobPreparationAndReleaseTaskExecutionInformation>> listPreparationAndReleaseTaskStatusNextAsync(final String nextPageLink) {
        return listPreparationAndReleaseTaskStatusNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>, Page<JobPreparationAndReleaseTaskExecutionInformation>>() {
                @Override
                public Page<JobPreparationAndReleaseTaskExecutionInformation> call(ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists the execution status of the Job Preparation and Job Release Task for the specified Job across the Compute Nodes where the Job has run.
     * This API returns the Job Preparation and Job Release Task status on all Compute Nodes that have run the Job Preparation or Job Release Task. This includes Compute Nodes which have since been removed from the Pool. If this API is invoked on a Job which has no Job Preparation or Job Release Task, the Batch service returns HTTP status code 409 (Conflict) with an error code of JobPreparationTaskNotSpecified.
     *
     * @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;JobPreparationAndReleaseTaskExecutionInformation&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>> listPreparationAndReleaseTaskStatusNextWithServiceResponseAsync(final String nextPageLink) {
        return listPreparationAndReleaseTaskStatusNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>, Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>> call(ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listPreparationAndReleaseTaskStatusNextWithServiceResponseAsync(nextPageLink, null));
                }
            });
    }

    /**
     * Lists the execution status of the Job Preparation and Job Release Task for the specified Job across the Compute Nodes where the Job has run.
     * This API returns the Job Preparation and Job Release Task status on all Compute Nodes that have run the Job Preparation or Job Release Task. This includes Compute Nodes which have since been removed from the Pool. If this API is invoked on a Job which has no Job Preparation or Job Release Task, the Batch service returns HTTP status code 409 (Conflict) with an error code of JobPreparationTaskNotSpecified.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;JobPreparationAndReleaseTaskExecutionInformation&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>> listPreparationAndReleaseTaskStatusNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        final JobListPreparationAndReleaseTaskStatusNextOptions jobListPreparationAndReleaseTaskStatusNextOptions = 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.listPreparationAndReleaseTaskStatusNext(nextUrl, this.client.acceptLanguage(), clientRequestId, returnClientRequestId, ocpDateConverted, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders> result = listPreparationAndReleaseTaskStatusNextDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Lists the execution status of the Job Preparation and Job Release Task for the specified Job across the Compute Nodes where the Job has run.
     * This API returns the Job Preparation and Job Release Task status on all Compute Nodes that have run the Job Preparation or Job Release Task. This includes Compute Nodes which have since been removed from the Pool. If this API is invoked on a Job which has no Job Preparation or Job Release Task, the Batch service returns HTTP status code 409 (Conflict) with an error code of JobPreparationTaskNotSpecified.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param jobListPreparationAndReleaseTaskStatusNextOptions 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;JobPreparationAndReleaseTaskExecutionInformation&gt; object if successful.
     */
    public PagedList<JobPreparationAndReleaseTaskExecutionInformation> listPreparationAndReleaseTaskStatusNext(final String nextPageLink, final JobListPreparationAndReleaseTaskStatusNextOptions jobListPreparationAndReleaseTaskStatusNextOptions) {
        ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders> response = listPreparationAndReleaseTaskStatusNextSinglePageAsync(nextPageLink, jobListPreparationAndReleaseTaskStatusNextOptions).toBlocking().single();
        return new PagedList<JobPreparationAndReleaseTaskExecutionInformation>(response.body()) {
            @Override
            public Page<JobPreparationAndReleaseTaskExecutionInformation> nextPage(String nextPageLink) {
                return listPreparationAndReleaseTaskStatusNextSinglePageAsync(nextPageLink, jobListPreparationAndReleaseTaskStatusNextOptions).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists the execution status of the Job Preparation and Job Release Task for the specified Job across the Compute Nodes where the Job has run.
     * This API returns the Job Preparation and Job Release Task status on all Compute Nodes that have run the Job Preparation or Job Release Task. This includes Compute Nodes which have since been removed from the Pool. If this API is invoked on a Job which has no Job Preparation or Job Release Task, the Batch service returns HTTP status code 409 (Conflict) with an error code of JobPreparationTaskNotSpecified.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param jobListPreparationAndReleaseTaskStatusNextOptions 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<JobPreparationAndReleaseTaskExecutionInformation>> listPreparationAndReleaseTaskStatusNextAsync(final String nextPageLink, final JobListPreparationAndReleaseTaskStatusNextOptions jobListPreparationAndReleaseTaskStatusNextOptions, final ServiceFuture<List<JobPreparationAndReleaseTaskExecutionInformation>> serviceFuture, final ListOperationCallback<JobPreparationAndReleaseTaskExecutionInformation> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listPreparationAndReleaseTaskStatusNextSinglePageAsync(nextPageLink, jobListPreparationAndReleaseTaskStatusNextOptions),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>> call(String nextPageLink) {
                    return listPreparationAndReleaseTaskStatusNextSinglePageAsync(nextPageLink, jobListPreparationAndReleaseTaskStatusNextOptions);
                }
            },
            serviceCallback);
    }

    /**
     * Lists the execution status of the Job Preparation and Job Release Task for the specified Job across the Compute Nodes where the Job has run.
     * This API returns the Job Preparation and Job Release Task status on all Compute Nodes that have run the Job Preparation or Job Release Task. This includes Compute Nodes which have since been removed from the Pool. If this API is invoked on a Job which has no Job Preparation or Job Release Task, the Batch service returns HTTP status code 409 (Conflict) with an error code of JobPreparationTaskNotSpecified.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param jobListPreparationAndReleaseTaskStatusNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;JobPreparationAndReleaseTaskExecutionInformation&gt; object
     */
    public Observable<Page<JobPreparationAndReleaseTaskExecutionInformation>> listPreparationAndReleaseTaskStatusNextAsync(final String nextPageLink, final JobListPreparationAndReleaseTaskStatusNextOptions jobListPreparationAndReleaseTaskStatusNextOptions) {
        return listPreparationAndReleaseTaskStatusNextWithServiceResponseAsync(nextPageLink, jobListPreparationAndReleaseTaskStatusNextOptions)
            .map(new Func1<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>, Page<JobPreparationAndReleaseTaskExecutionInformation>>() {
                @Override
                public Page<JobPreparationAndReleaseTaskExecutionInformation> call(ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists the execution status of the Job Preparation and Job Release Task for the specified Job across the Compute Nodes where the Job has run.
     * This API returns the Job Preparation and Job Release Task status on all Compute Nodes that have run the Job Preparation or Job Release Task. This includes Compute Nodes which have since been removed from the Pool. If this API is invoked on a Job which has no Job Preparation or Job Release Task, the Batch service returns HTTP status code 409 (Conflict) with an error code of JobPreparationTaskNotSpecified.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param jobListPreparationAndReleaseTaskStatusNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;JobPreparationAndReleaseTaskExecutionInformation&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>> listPreparationAndReleaseTaskStatusNextWithServiceResponseAsync(final String nextPageLink, final JobListPreparationAndReleaseTaskStatusNextOptions jobListPreparationAndReleaseTaskStatusNextOptions) {
        return listPreparationAndReleaseTaskStatusNextSinglePageAsync(nextPageLink, jobListPreparationAndReleaseTaskStatusNextOptions)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>, Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>> call(ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listPreparationAndReleaseTaskStatusNextWithServiceResponseAsync(nextPageLink, jobListPreparationAndReleaseTaskStatusNextOptions));
                }
            });
    }

    /**
     * Lists the execution status of the Job Preparation and Job Release Task for the specified Job across the Compute Nodes where the Job has run.
     * This API returns the Job Preparation and Job Release Task status on all Compute Nodes that have run the Job Preparation or Job Release Task. This includes Compute Nodes which have since been removed from the Pool. If this API is invoked on a Job which has no Job Preparation or Job Release Task, the Batch service returns HTTP status code 409 (Conflict) with an error code of JobPreparationTaskNotSpecified.
     *
    ServiceResponseWithHeaders<PageImpl<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders> * @param nextPageLink The NextLink from the previous successful call to List operation.
    ServiceResponseWithHeaders<PageImpl<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders> * @param jobListPreparationAndReleaseTaskStatusNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;JobPreparationAndReleaseTaskExecutionInformation&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>> listPreparationAndReleaseTaskStatusNextSinglePageAsync(final String nextPageLink, final JobListPreparationAndReleaseTaskStatusNextOptions jobListPreparationAndReleaseTaskStatusNextOptions) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        Validator.validate(jobListPreparationAndReleaseTaskStatusNextOptions);
        UUID clientRequestId = null;
        if (jobListPreparationAndReleaseTaskStatusNextOptions != null) {
            clientRequestId = jobListPreparationAndReleaseTaskStatusNextOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (jobListPreparationAndReleaseTaskStatusNextOptions != null) {
            returnClientRequestId = jobListPreparationAndReleaseTaskStatusNextOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (jobListPreparationAndReleaseTaskStatusNextOptions != null) {
            ocpDate = jobListPreparationAndReleaseTaskStatusNextOptions.ocpDate();
        }
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.listPreparationAndReleaseTaskStatusNext(nextUrl, this.client.acceptLanguage(), clientRequestId, returnClientRequestId, ocpDateConverted, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders> result = listPreparationAndReleaseTaskStatusNextDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<JobPreparationAndReleaseTaskExecutionInformation>, JobListPreparationAndReleaseTaskStatusHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

}
