/**
 * 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.Tasks;
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.CloudTask;
import com.microsoft.azure.batch.protocol.models.CloudTaskListSubtasksResult;
import com.microsoft.azure.batch.protocol.models.PageImpl;
import com.microsoft.azure.batch.protocol.models.TaskAddCollectionHeaders;
import com.microsoft.azure.batch.protocol.models.TaskAddCollectionOptions;
import com.microsoft.azure.batch.protocol.models.TaskAddCollectionParameter;
import com.microsoft.azure.batch.protocol.models.TaskAddCollectionResult;
import com.microsoft.azure.batch.protocol.models.TaskAddHeaders;
import com.microsoft.azure.batch.protocol.models.TaskAddOptions;
import com.microsoft.azure.batch.protocol.models.TaskAddParameter;
import com.microsoft.azure.batch.protocol.models.TaskConstraints;
import com.microsoft.azure.batch.protocol.models.TaskDeleteHeaders;
import com.microsoft.azure.batch.protocol.models.TaskDeleteOptions;
import com.microsoft.azure.batch.protocol.models.TaskGetHeaders;
import com.microsoft.azure.batch.protocol.models.TaskGetOptions;
import com.microsoft.azure.batch.protocol.models.TaskListHeaders;
import com.microsoft.azure.batch.protocol.models.TaskListNextOptions;
import com.microsoft.azure.batch.protocol.models.TaskListOptions;
import com.microsoft.azure.batch.protocol.models.TaskListSubtasksHeaders;
import com.microsoft.azure.batch.protocol.models.TaskListSubtasksOptions;
import com.microsoft.azure.batch.protocol.models.TaskReactivateHeaders;
import com.microsoft.azure.batch.protocol.models.TaskReactivateOptions;
import com.microsoft.azure.batch.protocol.models.TaskTerminateHeaders;
import com.microsoft.azure.batch.protocol.models.TaskTerminateOptions;
import com.microsoft.azure.batch.protocol.models.TaskUpdateHeaders;
import com.microsoft.azure.batch.protocol.models.TaskUpdateOptions;
import com.microsoft.azure.batch.protocol.models.TaskUpdateParameter;
import com.microsoft.azure.ListOperationCallback;
import com.microsoft.azure.Page;
import com.microsoft.azure.PagedList;
import com.microsoft.rest.DateTimeRfc1123;
import com.microsoft.rest.ServiceCallback;
import com.microsoft.rest.ServiceFuture;
import com.microsoft.rest.ServiceResponseWithHeaders;
import com.microsoft.rest.Validator;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import okhttp3.ResponseBody;
import org.joda.time.DateTime;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.HTTP;
import retrofit2.http.Path;
import retrofit2.http.POST;
import retrofit2.http.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 Tasks.
 */
public class TasksImpl implements Tasks {
    /** The Retrofit service to perform REST calls. */
    private TasksService service;
    /** The service client containing this operation class. */
    private BatchServiceClientImpl client;

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

    /**
     * The interface defining all the services for Tasks to be
     * used by Retrofit to perform actually REST calls.
     */
    interface TasksService {
        @Headers({ "Content-Type: application/json; odata=minimalmetadata; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.batch.protocol.Tasks add" })
        @POST("jobs/{jobId}/tasks")
        Observable<Response<ResponseBody>> add(@Path("jobId") String jobId, @Body TaskAddParameter task, @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.Tasks list" })
        @GET("jobs/{jobId}/tasks")
        Observable<Response<ResponseBody>> list(@Path("jobId") String jobId, @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; odata=minimalmetadata; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.batch.protocol.Tasks addCollection" })
        @POST("jobs/{jobId}/addtaskcollection")
        Observable<Response<ResponseBody>> addCollection(@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, @Body TaskAddCollectionParameter taskCollection, @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.Tasks delete" })
        @HTTP(path = "jobs/{jobId}/tasks/{taskId}", method = "DELETE", hasBody = true)
        Observable<Response<ResponseBody>> delete(@Path("jobId") String jobId, @Path("taskId") String taskId, @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.Tasks get" })
        @GET("jobs/{jobId}/tasks/{taskId}")
        Observable<Response<ResponseBody>> get(@Path("jobId") String jobId, @Path("taskId") String taskId, @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.Tasks update" })
        @PUT("jobs/{jobId}/tasks/{taskId}")
        Observable<Response<ResponseBody>> update(@Path("jobId") String jobId, @Path("taskId") String taskId, @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 TaskUpdateParameter taskUpdateParameter, @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.Tasks listSubtasks" })
        @GET("jobs/{jobId}/tasks/{taskId}/subtasksinfo")
        Observable<Response<ResponseBody>> listSubtasks(@Path("jobId") String jobId, @Path("taskId") String taskId, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Query("$select") String select, @Query("timeout") Integer timeout, @Header("client-request-id") UUID clientRequestId, @Header("return-client-request-id") Boolean returnClientRequestId, @Header("ocp-date") DateTimeRfc1123 ocpDate, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.batch.protocol.Tasks terminate" })
        @POST("jobs/{jobId}/tasks/{taskId}/terminate")
        Observable<Response<ResponseBody>> terminate(@Path("jobId") String jobId, @Path("taskId") String taskId, @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.Tasks reactivate" })
        @POST("jobs/{jobId}/tasks/{taskId}/reactivate")
        Observable<Response<ResponseBody>> reactivate(@Path("jobId") String jobId, @Path("taskId") String taskId, @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.Tasks listNext" })
        @GET
        Observable<Response<ResponseBody>> listNext(@Url String nextUrl, @Header("accept-language") String acceptLanguage, @Header("client-request-id") UUID clientRequestId, @Header("return-client-request-id") Boolean returnClientRequestId, @Header("ocp-date") DateTimeRfc1123 ocpDate, @Header("User-Agent") String userAgent);

    }

    /**
     * Adds a Task to the specified Job.
     * The maximum lifetime of a Task from addition to completion is 180 days. If a Task has not completed within 180 days of being added it will be terminated by the Batch service and left in whatever state it was in at that time.
     *
     * @param jobId The ID of the Job to which the Task is to be added.
     * @param task The Task 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(String jobId, TaskAddParameter task) {
        addWithServiceResponseAsync(jobId, task).toBlocking().single().body();
    }

    /**
     * Adds a Task to the specified Job.
     * The maximum lifetime of a Task from addition to completion is 180 days. If a Task has not completed within 180 days of being added it will be terminated by the Batch service and left in whatever state it was in at that time.
     *
     * @param jobId The ID of the Job to which the Task is to be added.
     * @param task The Task 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(String jobId, TaskAddParameter task, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(addWithServiceResponseAsync(jobId, task), serviceCallback);
    }

    /**
     * Adds a Task to the specified Job.
     * The maximum lifetime of a Task from addition to completion is 180 days. If a Task has not completed within 180 days of being added it will be terminated by the Batch service and left in whatever state it was in at that time.
     *
     * @param jobId The ID of the Job to which the Task is to be added.
     * @param task The Task to be added.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> addAsync(String jobId, TaskAddParameter task) {
        return addWithServiceResponseAsync(jobId, task).map(new Func1<ServiceResponseWithHeaders<Void, TaskAddHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, TaskAddHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Adds a Task to the specified Job.
     * The maximum lifetime of a Task from addition to completion is 180 days. If a Task has not completed within 180 days of being added it will be terminated by the Batch service and left in whatever state it was in at that time.
     *
     * @param jobId The ID of the Job to which the Task is to be added.
     * @param task The Task to be added.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, TaskAddHeaders>> addWithServiceResponseAsync(String jobId, TaskAddParameter task) {
        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 (task == null) {
            throw new IllegalArgumentException("Parameter task 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(task);
        final TaskAddOptions taskAddOptions = 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(jobId, task, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, TaskAddHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, TaskAddHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, TaskAddHeaders> clientResponse = addDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Adds a Task to the specified Job.
     * The maximum lifetime of a Task from addition to completion is 180 days. If a Task has not completed within 180 days of being added it will be terminated by the Batch service and left in whatever state it was in at that time.
     *
     * @param jobId The ID of the Job to which the Task is to be added.
     * @param task The Task to be added.
     * @param taskAddOptions 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(String jobId, TaskAddParameter task, TaskAddOptions taskAddOptions) {
        addWithServiceResponseAsync(jobId, task, taskAddOptions).toBlocking().single().body();
    }

    /**
     * Adds a Task to the specified Job.
     * The maximum lifetime of a Task from addition to completion is 180 days. If a Task has not completed within 180 days of being added it will be terminated by the Batch service and left in whatever state it was in at that time.
     *
     * @param jobId The ID of the Job to which the Task is to be added.
     * @param task The Task to be added.
     * @param taskAddOptions 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(String jobId, TaskAddParameter task, TaskAddOptions taskAddOptions, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(addWithServiceResponseAsync(jobId, task, taskAddOptions), serviceCallback);
    }

    /**
     * Adds a Task to the specified Job.
     * The maximum lifetime of a Task from addition to completion is 180 days. If a Task has not completed within 180 days of being added it will be terminated by the Batch service and left in whatever state it was in at that time.
     *
     * @param jobId The ID of the Job to which the Task is to be added.
     * @param task The Task to be added.
     * @param taskAddOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> addAsync(String jobId, TaskAddParameter task, TaskAddOptions taskAddOptions) {
        return addWithServiceResponseAsync(jobId, task, taskAddOptions).map(new Func1<ServiceResponseWithHeaders<Void, TaskAddHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, TaskAddHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Adds a Task to the specified Job.
     * The maximum lifetime of a Task from addition to completion is 180 days. If a Task has not completed within 180 days of being added it will be terminated by the Batch service and left in whatever state it was in at that time.
     *
     * @param jobId The ID of the Job to which the Task is to be added.
     * @param task The Task to be added.
     * @param taskAddOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, TaskAddHeaders>> addWithServiceResponseAsync(String jobId, TaskAddParameter task, TaskAddOptions taskAddOptions) {
        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 (task == null) {
            throw new IllegalArgumentException("Parameter task 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(task);
        Validator.validate(taskAddOptions);
        Integer timeout = null;
        if (taskAddOptions != null) {
            timeout = taskAddOptions.timeout();
        }
        UUID clientRequestId = null;
        if (taskAddOptions != null) {
            clientRequestId = taskAddOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (taskAddOptions != null) {
            returnClientRequestId = taskAddOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (taskAddOptions != null) {
            ocpDate = taskAddOptions.ocpDate();
        }
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.add(jobId, task, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, TaskAddHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, TaskAddHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, TaskAddHeaders> clientResponse = addDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Lists all of the Tasks that are associated with the specified Job.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @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;CloudTask&gt; object if successful.
     */
    public PagedList<CloudTask> list(final String jobId) {
        ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders> response = listSinglePageAsync(jobId).toBlocking().single();
        return new PagedList<CloudTask>(response.body()) {
            @Override
            public Page<CloudTask> nextPage(String nextPageLink) {
                return listNextSinglePageAsync(nextPageLink, null).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists all of the Tasks that are associated with the specified Job.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @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<CloudTask>> listAsync(final String jobId, final ListOperationCallback<CloudTask> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listSinglePageAsync(jobId),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>> call(String nextPageLink) {
                    return listNextSinglePageAsync(nextPageLink, null);
                }
            },
            serviceCallback);
    }

    /**
     * Lists all of the Tasks that are associated with the specified Job.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @param jobId The ID of the Job.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CloudTask&gt; object
     */
    public Observable<Page<CloudTask>> listAsync(final String jobId) {
        return listWithServiceResponseAsync(jobId)
            .map(new Func1<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>, Page<CloudTask>>() {
                @Override
                public Page<CloudTask> call(ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists all of the Tasks that are associated with the specified Job.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @param jobId The ID of the Job.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CloudTask&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>> listWithServiceResponseAsync(final String jobId) {
        return listSinglePageAsync(jobId)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>, Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>> call(ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders> 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 Tasks that are associated with the specified Job.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @param jobId The ID of the Job.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CloudTask&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>> listSinglePageAsync(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 TaskListOptions taskListOptions = 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(jobId, 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<CloudTask>, TaskListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<CloudTask>, TaskListHeaders> result = listDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Lists all of the Tasks that are associated with the specified Job.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @param jobId The ID of the Job.
     * @param taskListOptions 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;CloudTask&gt; object if successful.
     */
    public PagedList<CloudTask> list(final String jobId, final TaskListOptions taskListOptions) {
        ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders> response = listSinglePageAsync(jobId, taskListOptions).toBlocking().single();
        return new PagedList<CloudTask>(response.body()) {
            @Override
            public Page<CloudTask> nextPage(String nextPageLink) {
                TaskListNextOptions taskListNextOptions = null;
                if (taskListOptions != null) {
                    taskListNextOptions = new TaskListNextOptions();
                    taskListNextOptions.withClientRequestId(taskListOptions.clientRequestId());
                    taskListNextOptions.withReturnClientRequestId(taskListOptions.returnClientRequestId());
                    taskListNextOptions.withOcpDate(taskListOptions.ocpDate());
                }
                return listNextSinglePageAsync(nextPageLink, taskListNextOptions).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists all of the Tasks that are associated with the specified Job.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @param jobId The ID of the Job.
     * @param taskListOptions 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<CloudTask>> listAsync(final String jobId, final TaskListOptions taskListOptions, final ListOperationCallback<CloudTask> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listSinglePageAsync(jobId, taskListOptions),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>> call(String nextPageLink) {
                    TaskListNextOptions taskListNextOptions = null;
                    if (taskListOptions != null) {
                        taskListNextOptions = new TaskListNextOptions();
                        taskListNextOptions.withClientRequestId(taskListOptions.clientRequestId());
                        taskListNextOptions.withReturnClientRequestId(taskListOptions.returnClientRequestId());
                        taskListNextOptions.withOcpDate(taskListOptions.ocpDate());
                    }
                    return listNextSinglePageAsync(nextPageLink, taskListNextOptions);
                }
            },
            serviceCallback);
    }

    /**
     * Lists all of the Tasks that are associated with the specified Job.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @param jobId The ID of the Job.
     * @param taskListOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CloudTask&gt; object
     */
    public Observable<Page<CloudTask>> listAsync(final String jobId, final TaskListOptions taskListOptions) {
        return listWithServiceResponseAsync(jobId, taskListOptions)
            .map(new Func1<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>, Page<CloudTask>>() {
                @Override
                public Page<CloudTask> call(ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists all of the Tasks that are associated with the specified Job.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @param jobId The ID of the Job.
     * @param taskListOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CloudTask&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>> listWithServiceResponseAsync(final String jobId, final TaskListOptions taskListOptions) {
        return listSinglePageAsync(jobId, taskListOptions)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>, Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>> call(ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    TaskListNextOptions taskListNextOptions = null;
                    if (taskListOptions != null) {
                        taskListNextOptions = new TaskListNextOptions();
                        taskListNextOptions.withClientRequestId(taskListOptions.clientRequestId());
                        taskListNextOptions.withReturnClientRequestId(taskListOptions.returnClientRequestId());
                        taskListNextOptions.withOcpDate(taskListOptions.ocpDate());
                    }
                    return Observable.just(page).concatWith(listNextWithServiceResponseAsync(nextPageLink, taskListNextOptions));
                }
            });
    }

    /**
     * Lists all of the Tasks that are associated with the specified Job.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
    ServiceResponseWithHeaders<PageImpl<CloudTask>, TaskListHeaders> * @param jobId The ID of the Job.
    ServiceResponseWithHeaders<PageImpl<CloudTask>, TaskListHeaders> * @param taskListOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CloudTask&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>> listSinglePageAsync(final String jobId, final TaskListOptions taskListOptions) {
        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(taskListOptions);
        String filter = null;
        if (taskListOptions != null) {
            filter = taskListOptions.filter();
        }
        String select = null;
        if (taskListOptions != null) {
            select = taskListOptions.select();
        }
        String expand = null;
        if (taskListOptions != null) {
            expand = taskListOptions.expand();
        }
        Integer maxResults = null;
        if (taskListOptions != null) {
            maxResults = taskListOptions.maxResults();
        }
        Integer timeout = null;
        if (taskListOptions != null) {
            timeout = taskListOptions.timeout();
        }
        UUID clientRequestId = null;
        if (taskListOptions != null) {
            clientRequestId = taskListOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (taskListOptions != null) {
            returnClientRequestId = taskListOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (taskListOptions != null) {
            ocpDate = taskListOptions.ocpDate();
        }
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.list(jobId, 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<CloudTask>, TaskListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<CloudTask>, TaskListHeaders> result = listDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Adds a collection of Tasks to the specified Job.
     * Note that each Task must have a unique ID. The Batch service may not return the results for each Task in the same order the Tasks were submitted in this request. If the server times out or the connection is closed during the request, the request may have been partially or fully processed, or not at all. In such cases, the user should re-issue the request. Note that it is up to the user to correctly handle failures when re-issuing a request. For example, you should use the same Task IDs during a retry so that if the prior operation succeeded, the retry will not create extra Tasks unexpectedly. If the response contains any Tasks which failed to add, a client can retry the request. In a retry, it is most efficient to resubmit only Tasks that failed to add, and to omit Tasks that were successfully added on the first attempt. The maximum lifetime of a Task from addition to completion is 180 days. If a Task has not completed within 180 days of being added it will be terminated by the Batch service and left in whatever state it was in at that time.
     *
     * @param jobId The ID of the Job to which the Task collection is to be added.
     * @param value The collection of Tasks to add. The maximum count of Tasks is 100. The total serialized size of this collection must be less than 1MB. If it is greater than 1MB (for example if each Task has 100's of resource files or environment variables), the request will fail with code 'RequestBodyTooLarge' and should be retried again with fewer Tasks.
     * @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 TaskAddCollectionResult object if successful.
     */
    public TaskAddCollectionResult addCollection(String jobId, List<TaskAddParameter> value) {
        return addCollectionWithServiceResponseAsync(jobId, value).toBlocking().single().body();
    }

    /**
     * Adds a collection of Tasks to the specified Job.
     * Note that each Task must have a unique ID. The Batch service may not return the results for each Task in the same order the Tasks were submitted in this request. If the server times out or the connection is closed during the request, the request may have been partially or fully processed, or not at all. In such cases, the user should re-issue the request. Note that it is up to the user to correctly handle failures when re-issuing a request. For example, you should use the same Task IDs during a retry so that if the prior operation succeeded, the retry will not create extra Tasks unexpectedly. If the response contains any Tasks which failed to add, a client can retry the request. In a retry, it is most efficient to resubmit only Tasks that failed to add, and to omit Tasks that were successfully added on the first attempt. The maximum lifetime of a Task from addition to completion is 180 days. If a Task has not completed within 180 days of being added it will be terminated by the Batch service and left in whatever state it was in at that time.
     *
     * @param jobId The ID of the Job to which the Task collection is to be added.
     * @param value The collection of Tasks to add. The maximum count of Tasks is 100. The total serialized size of this collection must be less than 1MB. If it is greater than 1MB (for example if each Task has 100's of resource files or environment variables), the request will fail with code 'RequestBodyTooLarge' and should be retried again with fewer Tasks.
     * @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<TaskAddCollectionResult> addCollectionAsync(String jobId, List<TaskAddParameter> value, final ServiceCallback<TaskAddCollectionResult> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(addCollectionWithServiceResponseAsync(jobId, value), serviceCallback);
    }

    /**
     * Adds a collection of Tasks to the specified Job.
     * Note that each Task must have a unique ID. The Batch service may not return the results for each Task in the same order the Tasks were submitted in this request. If the server times out or the connection is closed during the request, the request may have been partially or fully processed, or not at all. In such cases, the user should re-issue the request. Note that it is up to the user to correctly handle failures when re-issuing a request. For example, you should use the same Task IDs during a retry so that if the prior operation succeeded, the retry will not create extra Tasks unexpectedly. If the response contains any Tasks which failed to add, a client can retry the request. In a retry, it is most efficient to resubmit only Tasks that failed to add, and to omit Tasks that were successfully added on the first attempt. The maximum lifetime of a Task from addition to completion is 180 days. If a Task has not completed within 180 days of being added it will be terminated by the Batch service and left in whatever state it was in at that time.
     *
     * @param jobId The ID of the Job to which the Task collection is to be added.
     * @param value The collection of Tasks to add. The maximum count of Tasks is 100. The total serialized size of this collection must be less than 1MB. If it is greater than 1MB (for example if each Task has 100's of resource files or environment variables), the request will fail with code 'RequestBodyTooLarge' and should be retried again with fewer Tasks.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the TaskAddCollectionResult object
     */
    public Observable<TaskAddCollectionResult> addCollectionAsync(String jobId, List<TaskAddParameter> value) {
        return addCollectionWithServiceResponseAsync(jobId, value).map(new Func1<ServiceResponseWithHeaders<TaskAddCollectionResult, TaskAddCollectionHeaders>, TaskAddCollectionResult>() {
            @Override
            public TaskAddCollectionResult call(ServiceResponseWithHeaders<TaskAddCollectionResult, TaskAddCollectionHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Adds a collection of Tasks to the specified Job.
     * Note that each Task must have a unique ID. The Batch service may not return the results for each Task in the same order the Tasks were submitted in this request. If the server times out or the connection is closed during the request, the request may have been partially or fully processed, or not at all. In such cases, the user should re-issue the request. Note that it is up to the user to correctly handle failures when re-issuing a request. For example, you should use the same Task IDs during a retry so that if the prior operation succeeded, the retry will not create extra Tasks unexpectedly. If the response contains any Tasks which failed to add, a client can retry the request. In a retry, it is most efficient to resubmit only Tasks that failed to add, and to omit Tasks that were successfully added on the first attempt. The maximum lifetime of a Task from addition to completion is 180 days. If a Task has not completed within 180 days of being added it will be terminated by the Batch service and left in whatever state it was in at that time.
     *
     * @param jobId The ID of the Job to which the Task collection is to be added.
     * @param value The collection of Tasks to add. The maximum count of Tasks is 100. The total serialized size of this collection must be less than 1MB. If it is greater than 1MB (for example if each Task has 100's of resource files or environment variables), the request will fail with code 'RequestBodyTooLarge' and should be retried again with fewer Tasks.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the TaskAddCollectionResult object
     */
    public Observable<ServiceResponseWithHeaders<TaskAddCollectionResult, TaskAddCollectionHeaders>> addCollectionWithServiceResponseAsync(String jobId, List<TaskAddParameter> value) {
        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 (value == null) {
            throw new IllegalArgumentException("Parameter value is required and cannot be null.");
        }
        Validator.validate(value);
        final TaskAddCollectionOptions taskAddCollectionOptions = null;
        Integer timeout = null;
        UUID clientRequestId = null;
        Boolean returnClientRequestId = null;
        DateTime ocpDate = null;
        TaskAddCollectionParameter taskCollection = new TaskAddCollectionParameter();
        taskCollection.withValue(value);
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.addCollection(jobId, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, taskCollection, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<TaskAddCollectionResult, TaskAddCollectionHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<TaskAddCollectionResult, TaskAddCollectionHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<TaskAddCollectionResult, TaskAddCollectionHeaders> clientResponse = addCollectionDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Adds a collection of Tasks to the specified Job.
     * Note that each Task must have a unique ID. The Batch service may not return the results for each Task in the same order the Tasks were submitted in this request. If the server times out or the connection is closed during the request, the request may have been partially or fully processed, or not at all. In such cases, the user should re-issue the request. Note that it is up to the user to correctly handle failures when re-issuing a request. For example, you should use the same Task IDs during a retry so that if the prior operation succeeded, the retry will not create extra Tasks unexpectedly. If the response contains any Tasks which failed to add, a client can retry the request. In a retry, it is most efficient to resubmit only Tasks that failed to add, and to omit Tasks that were successfully added on the first attempt. The maximum lifetime of a Task from addition to completion is 180 days. If a Task has not completed within 180 days of being added it will be terminated by the Batch service and left in whatever state it was in at that time.
     *
     * @param jobId The ID of the Job to which the Task collection is to be added.
     * @param value The collection of Tasks to add. The maximum count of Tasks is 100. The total serialized size of this collection must be less than 1MB. If it is greater than 1MB (for example if each Task has 100's of resource files or environment variables), the request will fail with code 'RequestBodyTooLarge' and should be retried again with fewer Tasks.
     * @param taskAddCollectionOptions 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 TaskAddCollectionResult object if successful.
     */
    public TaskAddCollectionResult addCollection(String jobId, List<TaskAddParameter> value, TaskAddCollectionOptions taskAddCollectionOptions) {
        return addCollectionWithServiceResponseAsync(jobId, value, taskAddCollectionOptions).toBlocking().single().body();
    }

    /**
     * Adds a collection of Tasks to the specified Job.
     * Note that each Task must have a unique ID. The Batch service may not return the results for each Task in the same order the Tasks were submitted in this request. If the server times out or the connection is closed during the request, the request may have been partially or fully processed, or not at all. In such cases, the user should re-issue the request. Note that it is up to the user to correctly handle failures when re-issuing a request. For example, you should use the same Task IDs during a retry so that if the prior operation succeeded, the retry will not create extra Tasks unexpectedly. If the response contains any Tasks which failed to add, a client can retry the request. In a retry, it is most efficient to resubmit only Tasks that failed to add, and to omit Tasks that were successfully added on the first attempt. The maximum lifetime of a Task from addition to completion is 180 days. If a Task has not completed within 180 days of being added it will be terminated by the Batch service and left in whatever state it was in at that time.
     *
     * @param jobId The ID of the Job to which the Task collection is to be added.
     * @param value The collection of Tasks to add. The maximum count of Tasks is 100. The total serialized size of this collection must be less than 1MB. If it is greater than 1MB (for example if each Task has 100's of resource files or environment variables), the request will fail with code 'RequestBodyTooLarge' and should be retried again with fewer Tasks.
     * @param taskAddCollectionOptions 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<TaskAddCollectionResult> addCollectionAsync(String jobId, List<TaskAddParameter> value, TaskAddCollectionOptions taskAddCollectionOptions, final ServiceCallback<TaskAddCollectionResult> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(addCollectionWithServiceResponseAsync(jobId, value, taskAddCollectionOptions), serviceCallback);
    }

    /**
     * Adds a collection of Tasks to the specified Job.
     * Note that each Task must have a unique ID. The Batch service may not return the results for each Task in the same order the Tasks were submitted in this request. If the server times out or the connection is closed during the request, the request may have been partially or fully processed, or not at all. In such cases, the user should re-issue the request. Note that it is up to the user to correctly handle failures when re-issuing a request. For example, you should use the same Task IDs during a retry so that if the prior operation succeeded, the retry will not create extra Tasks unexpectedly. If the response contains any Tasks which failed to add, a client can retry the request. In a retry, it is most efficient to resubmit only Tasks that failed to add, and to omit Tasks that were successfully added on the first attempt. The maximum lifetime of a Task from addition to completion is 180 days. If a Task has not completed within 180 days of being added it will be terminated by the Batch service and left in whatever state it was in at that time.
     *
     * @param jobId The ID of the Job to which the Task collection is to be added.
     * @param value The collection of Tasks to add. The maximum count of Tasks is 100. The total serialized size of this collection must be less than 1MB. If it is greater than 1MB (for example if each Task has 100's of resource files or environment variables), the request will fail with code 'RequestBodyTooLarge' and should be retried again with fewer Tasks.
     * @param taskAddCollectionOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the TaskAddCollectionResult object
     */
    public Observable<TaskAddCollectionResult> addCollectionAsync(String jobId, List<TaskAddParameter> value, TaskAddCollectionOptions taskAddCollectionOptions) {
        return addCollectionWithServiceResponseAsync(jobId, value, taskAddCollectionOptions).map(new Func1<ServiceResponseWithHeaders<TaskAddCollectionResult, TaskAddCollectionHeaders>, TaskAddCollectionResult>() {
            @Override
            public TaskAddCollectionResult call(ServiceResponseWithHeaders<TaskAddCollectionResult, TaskAddCollectionHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Adds a collection of Tasks to the specified Job.
     * Note that each Task must have a unique ID. The Batch service may not return the results for each Task in the same order the Tasks were submitted in this request. If the server times out or the connection is closed during the request, the request may have been partially or fully processed, or not at all. In such cases, the user should re-issue the request. Note that it is up to the user to correctly handle failures when re-issuing a request. For example, you should use the same Task IDs during a retry so that if the prior operation succeeded, the retry will not create extra Tasks unexpectedly. If the response contains any Tasks which failed to add, a client can retry the request. In a retry, it is most efficient to resubmit only Tasks that failed to add, and to omit Tasks that were successfully added on the first attempt. The maximum lifetime of a Task from addition to completion is 180 days. If a Task has not completed within 180 days of being added it will be terminated by the Batch service and left in whatever state it was in at that time.
     *
     * @param jobId The ID of the Job to which the Task collection is to be added.
     * @param value The collection of Tasks to add. The maximum count of Tasks is 100. The total serialized size of this collection must be less than 1MB. If it is greater than 1MB (for example if each Task has 100's of resource files or environment variables), the request will fail with code 'RequestBodyTooLarge' and should be retried again with fewer Tasks.
     * @param taskAddCollectionOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the TaskAddCollectionResult object
     */
    public Observable<ServiceResponseWithHeaders<TaskAddCollectionResult, TaskAddCollectionHeaders>> addCollectionWithServiceResponseAsync(String jobId, List<TaskAddParameter> value, TaskAddCollectionOptions taskAddCollectionOptions) {
        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 (value == null) {
            throw new IllegalArgumentException("Parameter value is required and cannot be null.");
        }
        Validator.validate(value);
        Validator.validate(taskAddCollectionOptions);
        Integer timeout = null;
        if (taskAddCollectionOptions != null) {
            timeout = taskAddCollectionOptions.timeout();
        }
        UUID clientRequestId = null;
        if (taskAddCollectionOptions != null) {
            clientRequestId = taskAddCollectionOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (taskAddCollectionOptions != null) {
            returnClientRequestId = taskAddCollectionOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (taskAddCollectionOptions != null) {
            ocpDate = taskAddCollectionOptions.ocpDate();
        }
        TaskAddCollectionParameter taskCollection = new TaskAddCollectionParameter();
        taskCollection.withValue(value);
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.addCollection(jobId, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, taskCollection, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<TaskAddCollectionResult, TaskAddCollectionHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<TaskAddCollectionResult, TaskAddCollectionHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<TaskAddCollectionResult, TaskAddCollectionHeaders> clientResponse = addCollectionDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Deletes a Task from the specified Job.
     * When a Task is deleted, all of the files in its directory on the Compute Node where it ran are also deleted (regardless of the retention time). For multi-instance Tasks, the delete Task operation applies synchronously to the primary task; subtasks and their files are then deleted asynchronously in the background.
     *
     * @param jobId The ID of the Job from which to delete the Task.
     * @param taskId The ID of the Task 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, String taskId) {
        deleteWithServiceResponseAsync(jobId, taskId).toBlocking().single().body();
    }

    /**
     * Deletes a Task from the specified Job.
     * When a Task is deleted, all of the files in its directory on the Compute Node where it ran are also deleted (regardless of the retention time). For multi-instance Tasks, the delete Task operation applies synchronously to the primary task; subtasks and their files are then deleted asynchronously in the background.
     *
     * @param jobId The ID of the Job from which to delete the Task.
     * @param taskId The ID of the Task 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, String taskId, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(deleteWithServiceResponseAsync(jobId, taskId), serviceCallback);
    }

    /**
     * Deletes a Task from the specified Job.
     * When a Task is deleted, all of the files in its directory on the Compute Node where it ran are also deleted (regardless of the retention time). For multi-instance Tasks, the delete Task operation applies synchronously to the primary task; subtasks and their files are then deleted asynchronously in the background.
     *
     * @param jobId The ID of the Job from which to delete the Task.
     * @param taskId The ID of the Task to delete.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> deleteAsync(String jobId, String taskId) {
        return deleteWithServiceResponseAsync(jobId, taskId).map(new Func1<ServiceResponseWithHeaders<Void, TaskDeleteHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, TaskDeleteHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Deletes a Task from the specified Job.
     * When a Task is deleted, all of the files in its directory on the Compute Node where it ran are also deleted (regardless of the retention time). For multi-instance Tasks, the delete Task operation applies synchronously to the primary task; subtasks and their files are then deleted asynchronously in the background.
     *
     * @param jobId The ID of the Job from which to delete the Task.
     * @param taskId The ID of the Task to delete.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, TaskDeleteHeaders>> deleteWithServiceResponseAsync(String jobId, String taskId) {
        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 (taskId == null) {
            throw new IllegalArgumentException("Parameter taskId 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 TaskDeleteOptions taskDeleteOptions = 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, taskId, 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, TaskDeleteHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, TaskDeleteHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, TaskDeleteHeaders> clientResponse = deleteDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Deletes a Task from the specified Job.
     * When a Task is deleted, all of the files in its directory on the Compute Node where it ran are also deleted (regardless of the retention time). For multi-instance Tasks, the delete Task operation applies synchronously to the primary task; subtasks and their files are then deleted asynchronously in the background.
     *
     * @param jobId The ID of the Job from which to delete the Task.
     * @param taskId The ID of the Task to delete.
     * @param taskDeleteOptions 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, String taskId, TaskDeleteOptions taskDeleteOptions) {
        deleteWithServiceResponseAsync(jobId, taskId, taskDeleteOptions).toBlocking().single().body();
    }

    /**
     * Deletes a Task from the specified Job.
     * When a Task is deleted, all of the files in its directory on the Compute Node where it ran are also deleted (regardless of the retention time). For multi-instance Tasks, the delete Task operation applies synchronously to the primary task; subtasks and their files are then deleted asynchronously in the background.
     *
     * @param jobId The ID of the Job from which to delete the Task.
     * @param taskId The ID of the Task to delete.
     * @param taskDeleteOptions 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, String taskId, TaskDeleteOptions taskDeleteOptions, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(deleteWithServiceResponseAsync(jobId, taskId, taskDeleteOptions), serviceCallback);
    }

    /**
     * Deletes a Task from the specified Job.
     * When a Task is deleted, all of the files in its directory on the Compute Node where it ran are also deleted (regardless of the retention time). For multi-instance Tasks, the delete Task operation applies synchronously to the primary task; subtasks and their files are then deleted asynchronously in the background.
     *
     * @param jobId The ID of the Job from which to delete the Task.
     * @param taskId The ID of the Task to delete.
     * @param taskDeleteOptions 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, String taskId, TaskDeleteOptions taskDeleteOptions) {
        return deleteWithServiceResponseAsync(jobId, taskId, taskDeleteOptions).map(new Func1<ServiceResponseWithHeaders<Void, TaskDeleteHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, TaskDeleteHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Deletes a Task from the specified Job.
     * When a Task is deleted, all of the files in its directory on the Compute Node where it ran are also deleted (regardless of the retention time). For multi-instance Tasks, the delete Task operation applies synchronously to the primary task; subtasks and their files are then deleted asynchronously in the background.
     *
     * @param jobId The ID of the Job from which to delete the Task.
     * @param taskId The ID of the Task to delete.
     * @param taskDeleteOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, TaskDeleteHeaders>> deleteWithServiceResponseAsync(String jobId, String taskId, TaskDeleteOptions taskDeleteOptions) {
        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 (taskId == null) {
            throw new IllegalArgumentException("Parameter taskId 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(taskDeleteOptions);
        Integer timeout = null;
        if (taskDeleteOptions != null) {
            timeout = taskDeleteOptions.timeout();
        }
        UUID clientRequestId = null;
        if (taskDeleteOptions != null) {
            clientRequestId = taskDeleteOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (taskDeleteOptions != null) {
            returnClientRequestId = taskDeleteOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (taskDeleteOptions != null) {
            ocpDate = taskDeleteOptions.ocpDate();
        }
        String ifMatch = null;
        if (taskDeleteOptions != null) {
            ifMatch = taskDeleteOptions.ifMatch();
        }
        String ifNoneMatch = null;
        if (taskDeleteOptions != null) {
            ifNoneMatch = taskDeleteOptions.ifNoneMatch();
        }
        DateTime ifModifiedSince = null;
        if (taskDeleteOptions != null) {
            ifModifiedSince = taskDeleteOptions.ifModifiedSince();
        }
        DateTime ifUnmodifiedSince = null;
        if (taskDeleteOptions != null) {
            ifUnmodifiedSince = taskDeleteOptions.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, taskId, 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, TaskDeleteHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, TaskDeleteHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, TaskDeleteHeaders> clientResponse = deleteDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Gets information about the specified Task.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @param jobId The ID of the Job that contains the Task.
     * @param taskId The ID of the Task to get information about.
     * @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 CloudTask object if successful.
     */
    public CloudTask get(String jobId, String taskId) {
        return getWithServiceResponseAsync(jobId, taskId).toBlocking().single().body();
    }

    /**
     * Gets information about the specified Task.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @param jobId The ID of the Job that contains the Task.
     * @param taskId The ID of the Task to get information about.
     * @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<CloudTask> getAsync(String jobId, String taskId, final ServiceCallback<CloudTask> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(getWithServiceResponseAsync(jobId, taskId), serviceCallback);
    }

    /**
     * Gets information about the specified Task.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @param jobId The ID of the Job that contains the Task.
     * @param taskId The ID of the Task to get information about.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CloudTask object
     */
    public Observable<CloudTask> getAsync(String jobId, String taskId) {
        return getWithServiceResponseAsync(jobId, taskId).map(new Func1<ServiceResponseWithHeaders<CloudTask, TaskGetHeaders>, CloudTask>() {
            @Override
            public CloudTask call(ServiceResponseWithHeaders<CloudTask, TaskGetHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets information about the specified Task.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @param jobId The ID of the Job that contains the Task.
     * @param taskId The ID of the Task to get information about.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CloudTask object
     */
    public Observable<ServiceResponseWithHeaders<CloudTask, TaskGetHeaders>> getWithServiceResponseAsync(String jobId, String taskId) {
        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 (taskId == null) {
            throw new IllegalArgumentException("Parameter taskId 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 TaskGetOptions taskGetOptions = 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, taskId, 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<CloudTask, TaskGetHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<CloudTask, TaskGetHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<CloudTask, TaskGetHeaders> clientResponse = getDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Gets information about the specified Task.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @param jobId The ID of the Job that contains the Task.
     * @param taskId The ID of the Task to get information about.
     * @param taskGetOptions 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 CloudTask object if successful.
     */
    public CloudTask get(String jobId, String taskId, TaskGetOptions taskGetOptions) {
        return getWithServiceResponseAsync(jobId, taskId, taskGetOptions).toBlocking().single().body();
    }

    /**
     * Gets information about the specified Task.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @param jobId The ID of the Job that contains the Task.
     * @param taskId The ID of the Task to get information about.
     * @param taskGetOptions 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<CloudTask> getAsync(String jobId, String taskId, TaskGetOptions taskGetOptions, final ServiceCallback<CloudTask> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(getWithServiceResponseAsync(jobId, taskId, taskGetOptions), serviceCallback);
    }

    /**
     * Gets information about the specified Task.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @param jobId The ID of the Job that contains the Task.
     * @param taskId The ID of the Task to get information about.
     * @param taskGetOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CloudTask object
     */
    public Observable<CloudTask> getAsync(String jobId, String taskId, TaskGetOptions taskGetOptions) {
        return getWithServiceResponseAsync(jobId, taskId, taskGetOptions).map(new Func1<ServiceResponseWithHeaders<CloudTask, TaskGetHeaders>, CloudTask>() {
            @Override
            public CloudTask call(ServiceResponseWithHeaders<CloudTask, TaskGetHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets information about the specified Task.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @param jobId The ID of the Job that contains the Task.
     * @param taskId The ID of the Task to get information about.
     * @param taskGetOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CloudTask object
     */
    public Observable<ServiceResponseWithHeaders<CloudTask, TaskGetHeaders>> getWithServiceResponseAsync(String jobId, String taskId, TaskGetOptions taskGetOptions) {
        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 (taskId == null) {
            throw new IllegalArgumentException("Parameter taskId 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(taskGetOptions);
        String select = null;
        if (taskGetOptions != null) {
            select = taskGetOptions.select();
        }
        String expand = null;
        if (taskGetOptions != null) {
            expand = taskGetOptions.expand();
        }
        Integer timeout = null;
        if (taskGetOptions != null) {
            timeout = taskGetOptions.timeout();
        }
        UUID clientRequestId = null;
        if (taskGetOptions != null) {
            clientRequestId = taskGetOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (taskGetOptions != null) {
            returnClientRequestId = taskGetOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (taskGetOptions != null) {
            ocpDate = taskGetOptions.ocpDate();
        }
        String ifMatch = null;
        if (taskGetOptions != null) {
            ifMatch = taskGetOptions.ifMatch();
        }
        String ifNoneMatch = null;
        if (taskGetOptions != null) {
            ifNoneMatch = taskGetOptions.ifNoneMatch();
        }
        DateTime ifModifiedSince = null;
        if (taskGetOptions != null) {
            ifModifiedSince = taskGetOptions.ifModifiedSince();
        }
        DateTime ifUnmodifiedSince = null;
        if (taskGetOptions != null) {
            ifUnmodifiedSince = taskGetOptions.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, taskId, 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<CloudTask, TaskGetHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<CloudTask, TaskGetHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<CloudTask, TaskGetHeaders> clientResponse = getDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Updates the properties of the specified Task.
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to update.
     * @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, String taskId) {
        updateWithServiceResponseAsync(jobId, taskId).toBlocking().single().body();
    }

    /**
     * Updates the properties of the specified Task.
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to update.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<Void> updateAsync(String jobId, String taskId, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(updateWithServiceResponseAsync(jobId, taskId), serviceCallback);
    }

    /**
     * Updates the properties of the specified Task.
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to update.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> updateAsync(String jobId, String taskId) {
        return updateWithServiceResponseAsync(jobId, taskId).map(new Func1<ServiceResponseWithHeaders<Void, TaskUpdateHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, TaskUpdateHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates the properties of the specified Task.
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to update.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, TaskUpdateHeaders>> updateWithServiceResponseAsync(String jobId, String taskId) {
        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 (taskId == null) {
            throw new IllegalArgumentException("Parameter taskId 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 TaskConstraints constraints = null;
        final TaskUpdateOptions taskUpdateOptions = 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;
        TaskUpdateParameter taskUpdateParameter = new TaskUpdateParameter();
        taskUpdateParameter.withConstraints(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, taskId, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, ifMatch, ifNoneMatch, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, taskUpdateParameter, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, TaskUpdateHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, TaskUpdateHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, TaskUpdateHeaders> clientResponse = updateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Updates the properties of the specified Task.
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to update.
     * @param constraints Constraints that apply to this Task. If omitted, the Task is given the default constraints. For multi-instance Tasks, updating the retention time applies only to the primary Task and not subtasks.
     * @param taskUpdateOptions 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, String taskId, TaskConstraints constraints, TaskUpdateOptions taskUpdateOptions) {
        updateWithServiceResponseAsync(jobId, taskId, constraints, taskUpdateOptions).toBlocking().single().body();
    }

    /**
     * Updates the properties of the specified Task.
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to update.
     * @param constraints Constraints that apply to this Task. If omitted, the Task is given the default constraints. For multi-instance Tasks, updating the retention time applies only to the primary Task and not subtasks.
     * @param taskUpdateOptions 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, String taskId, TaskConstraints constraints, TaskUpdateOptions taskUpdateOptions, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(updateWithServiceResponseAsync(jobId, taskId, constraints, taskUpdateOptions), serviceCallback);
    }

    /**
     * Updates the properties of the specified Task.
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to update.
     * @param constraints Constraints that apply to this Task. If omitted, the Task is given the default constraints. For multi-instance Tasks, updating the retention time applies only to the primary Task and not subtasks.
     * @param taskUpdateOptions 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, String taskId, TaskConstraints constraints, TaskUpdateOptions taskUpdateOptions) {
        return updateWithServiceResponseAsync(jobId, taskId, constraints, taskUpdateOptions).map(new Func1<ServiceResponseWithHeaders<Void, TaskUpdateHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, TaskUpdateHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates the properties of the specified Task.
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to update.
     * @param constraints Constraints that apply to this Task. If omitted, the Task is given the default constraints. For multi-instance Tasks, updating the retention time applies only to the primary Task and not subtasks.
     * @param taskUpdateOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, TaskUpdateHeaders>> updateWithServiceResponseAsync(String jobId, String taskId, TaskConstraints constraints, TaskUpdateOptions taskUpdateOptions) {
        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 (taskId == null) {
            throw new IllegalArgumentException("Parameter taskId 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(constraints);
        Validator.validate(taskUpdateOptions);
        Integer timeout = null;
        if (taskUpdateOptions != null) {
            timeout = taskUpdateOptions.timeout();
        }
        UUID clientRequestId = null;
        if (taskUpdateOptions != null) {
            clientRequestId = taskUpdateOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (taskUpdateOptions != null) {
            returnClientRequestId = taskUpdateOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (taskUpdateOptions != null) {
            ocpDate = taskUpdateOptions.ocpDate();
        }
        String ifMatch = null;
        if (taskUpdateOptions != null) {
            ifMatch = taskUpdateOptions.ifMatch();
        }
        String ifNoneMatch = null;
        if (taskUpdateOptions != null) {
            ifNoneMatch = taskUpdateOptions.ifNoneMatch();
        }
        DateTime ifModifiedSince = null;
        if (taskUpdateOptions != null) {
            ifModifiedSince = taskUpdateOptions.ifModifiedSince();
        }
        DateTime ifUnmodifiedSince = null;
        if (taskUpdateOptions != null) {
            ifUnmodifiedSince = taskUpdateOptions.ifUnmodifiedSince();
        }
        TaskUpdateParameter taskUpdateParameter = new TaskUpdateParameter();
        taskUpdateParameter.withConstraints(constraints);
        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, taskId, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, ifMatch, ifNoneMatch, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, taskUpdateParameter, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, TaskUpdateHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, TaskUpdateHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, TaskUpdateHeaders> clientResponse = updateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Lists all of the subtasks that are associated with the specified multi-instance Task.
     * If the Task is not a multi-instance Task then this returns an empty collection.
     *
     * @param jobId The ID of the Job.
     * @param taskId The ID of the Task.
     * @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 CloudTaskListSubtasksResult object if successful.
     */
    public CloudTaskListSubtasksResult listSubtasks(String jobId, String taskId) {
        return listSubtasksWithServiceResponseAsync(jobId, taskId).toBlocking().single().body();
    }

    /**
     * Lists all of the subtasks that are associated with the specified multi-instance Task.
     * If the Task is not a multi-instance Task then this returns an empty collection.
     *
     * @param jobId The ID of the Job.
     * @param taskId The ID of the Task.
     * @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<CloudTaskListSubtasksResult> listSubtasksAsync(String jobId, String taskId, final ServiceCallback<CloudTaskListSubtasksResult> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(listSubtasksWithServiceResponseAsync(jobId, taskId), serviceCallback);
    }

    /**
     * Lists all of the subtasks that are associated with the specified multi-instance Task.
     * If the Task is not a multi-instance Task then this returns an empty collection.
     *
     * @param jobId The ID of the Job.
     * @param taskId The ID of the Task.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CloudTaskListSubtasksResult object
     */
    public Observable<CloudTaskListSubtasksResult> listSubtasksAsync(String jobId, String taskId) {
        return listSubtasksWithServiceResponseAsync(jobId, taskId).map(new Func1<ServiceResponseWithHeaders<CloudTaskListSubtasksResult, TaskListSubtasksHeaders>, CloudTaskListSubtasksResult>() {
            @Override
            public CloudTaskListSubtasksResult call(ServiceResponseWithHeaders<CloudTaskListSubtasksResult, TaskListSubtasksHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Lists all of the subtasks that are associated with the specified multi-instance Task.
     * If the Task is not a multi-instance Task then this returns an empty collection.
     *
     * @param jobId The ID of the Job.
     * @param taskId The ID of the Task.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CloudTaskListSubtasksResult object
     */
    public Observable<ServiceResponseWithHeaders<CloudTaskListSubtasksResult, TaskListSubtasksHeaders>> listSubtasksWithServiceResponseAsync(String jobId, String taskId) {
        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 (taskId == null) {
            throw new IllegalArgumentException("Parameter taskId 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 TaskListSubtasksOptions taskListSubtasksOptions = null;
        String select = null;
        Integer timeout = null;
        UUID clientRequestId = null;
        Boolean returnClientRequestId = null;
        DateTime ocpDate = null;
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.listSubtasks(jobId, taskId, this.client.apiVersion(), this.client.acceptLanguage(), select, timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<CloudTaskListSubtasksResult, TaskListSubtasksHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<CloudTaskListSubtasksResult, TaskListSubtasksHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<CloudTaskListSubtasksResult, TaskListSubtasksHeaders> clientResponse = listSubtasksDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Lists all of the subtasks that are associated with the specified multi-instance Task.
     * If the Task is not a multi-instance Task then this returns an empty collection.
     *
     * @param jobId The ID of the Job.
     * @param taskId The ID of the Task.
     * @param taskListSubtasksOptions 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 CloudTaskListSubtasksResult object if successful.
     */
    public CloudTaskListSubtasksResult listSubtasks(String jobId, String taskId, TaskListSubtasksOptions taskListSubtasksOptions) {
        return listSubtasksWithServiceResponseAsync(jobId, taskId, taskListSubtasksOptions).toBlocking().single().body();
    }

    /**
     * Lists all of the subtasks that are associated with the specified multi-instance Task.
     * If the Task is not a multi-instance Task then this returns an empty collection.
     *
     * @param jobId The ID of the Job.
     * @param taskId The ID of the Task.
     * @param taskListSubtasksOptions 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<CloudTaskListSubtasksResult> listSubtasksAsync(String jobId, String taskId, TaskListSubtasksOptions taskListSubtasksOptions, final ServiceCallback<CloudTaskListSubtasksResult> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(listSubtasksWithServiceResponseAsync(jobId, taskId, taskListSubtasksOptions), serviceCallback);
    }

    /**
     * Lists all of the subtasks that are associated with the specified multi-instance Task.
     * If the Task is not a multi-instance Task then this returns an empty collection.
     *
     * @param jobId The ID of the Job.
     * @param taskId The ID of the Task.
     * @param taskListSubtasksOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CloudTaskListSubtasksResult object
     */
    public Observable<CloudTaskListSubtasksResult> listSubtasksAsync(String jobId, String taskId, TaskListSubtasksOptions taskListSubtasksOptions) {
        return listSubtasksWithServiceResponseAsync(jobId, taskId, taskListSubtasksOptions).map(new Func1<ServiceResponseWithHeaders<CloudTaskListSubtasksResult, TaskListSubtasksHeaders>, CloudTaskListSubtasksResult>() {
            @Override
            public CloudTaskListSubtasksResult call(ServiceResponseWithHeaders<CloudTaskListSubtasksResult, TaskListSubtasksHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Lists all of the subtasks that are associated with the specified multi-instance Task.
     * If the Task is not a multi-instance Task then this returns an empty collection.
     *
     * @param jobId The ID of the Job.
     * @param taskId The ID of the Task.
     * @param taskListSubtasksOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CloudTaskListSubtasksResult object
     */
    public Observable<ServiceResponseWithHeaders<CloudTaskListSubtasksResult, TaskListSubtasksHeaders>> listSubtasksWithServiceResponseAsync(String jobId, String taskId, TaskListSubtasksOptions taskListSubtasksOptions) {
        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 (taskId == null) {
            throw new IllegalArgumentException("Parameter taskId 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(taskListSubtasksOptions);
        String select = null;
        if (taskListSubtasksOptions != null) {
            select = taskListSubtasksOptions.select();
        }
        Integer timeout = null;
        if (taskListSubtasksOptions != null) {
            timeout = taskListSubtasksOptions.timeout();
        }
        UUID clientRequestId = null;
        if (taskListSubtasksOptions != null) {
            clientRequestId = taskListSubtasksOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (taskListSubtasksOptions != null) {
            returnClientRequestId = taskListSubtasksOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (taskListSubtasksOptions != null) {
            ocpDate = taskListSubtasksOptions.ocpDate();
        }
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.listSubtasks(jobId, taskId, this.client.apiVersion(), this.client.acceptLanguage(), select, timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<CloudTaskListSubtasksResult, TaskListSubtasksHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<CloudTaskListSubtasksResult, TaskListSubtasksHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<CloudTaskListSubtasksResult, TaskListSubtasksHeaders> clientResponse = listSubtasksDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Terminates the specified Task.
     * When the Task has been terminated, it moves to the completed state. For multi-instance Tasks, the terminate Task operation applies synchronously to the primary task; subtasks are then terminated asynchronously in the background.
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task 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, String taskId) {
        terminateWithServiceResponseAsync(jobId, taskId).toBlocking().single().body();
    }

    /**
     * Terminates the specified Task.
     * When the Task has been terminated, it moves to the completed state. For multi-instance Tasks, the terminate Task operation applies synchronously to the primary task; subtasks are then terminated asynchronously in the background.
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task 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, String taskId, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(terminateWithServiceResponseAsync(jobId, taskId), serviceCallback);
    }

    /**
     * Terminates the specified Task.
     * When the Task has been terminated, it moves to the completed state. For multi-instance Tasks, the terminate Task operation applies synchronously to the primary task; subtasks are then terminated asynchronously in the background.
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to terminate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> terminateAsync(String jobId, String taskId) {
        return terminateWithServiceResponseAsync(jobId, taskId).map(new Func1<ServiceResponseWithHeaders<Void, TaskTerminateHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, TaskTerminateHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Terminates the specified Task.
     * When the Task has been terminated, it moves to the completed state. For multi-instance Tasks, the terminate Task operation applies synchronously to the primary task; subtasks are then terminated asynchronously in the background.
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to terminate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, TaskTerminateHeaders>> terminateWithServiceResponseAsync(String jobId, String taskId) {
        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 (taskId == null) {
            throw new IllegalArgumentException("Parameter taskId 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 TaskTerminateOptions taskTerminateOptions = 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.terminate(jobId, taskId, 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, TaskTerminateHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, TaskTerminateHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, TaskTerminateHeaders> clientResponse = terminateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Terminates the specified Task.
     * When the Task has been terminated, it moves to the completed state. For multi-instance Tasks, the terminate Task operation applies synchronously to the primary task; subtasks are then terminated asynchronously in the background.
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to terminate.
     * @param taskTerminateOptions 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 taskId, TaskTerminateOptions taskTerminateOptions) {
        terminateWithServiceResponseAsync(jobId, taskId, taskTerminateOptions).toBlocking().single().body();
    }

    /**
     * Terminates the specified Task.
     * When the Task has been terminated, it moves to the completed state. For multi-instance Tasks, the terminate Task operation applies synchronously to the primary task; subtasks are then terminated asynchronously in the background.
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to terminate.
     * @param taskTerminateOptions 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 taskId, TaskTerminateOptions taskTerminateOptions, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(terminateWithServiceResponseAsync(jobId, taskId, taskTerminateOptions), serviceCallback);
    }

    /**
     * Terminates the specified Task.
     * When the Task has been terminated, it moves to the completed state. For multi-instance Tasks, the terminate Task operation applies synchronously to the primary task; subtasks are then terminated asynchronously in the background.
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to terminate.
     * @param taskTerminateOptions 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 taskId, TaskTerminateOptions taskTerminateOptions) {
        return terminateWithServiceResponseAsync(jobId, taskId, taskTerminateOptions).map(new Func1<ServiceResponseWithHeaders<Void, TaskTerminateHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, TaskTerminateHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Terminates the specified Task.
     * When the Task has been terminated, it moves to the completed state. For multi-instance Tasks, the terminate Task operation applies synchronously to the primary task; subtasks are then terminated asynchronously in the background.
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to terminate.
     * @param taskTerminateOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, TaskTerminateHeaders>> terminateWithServiceResponseAsync(String jobId, String taskId, TaskTerminateOptions taskTerminateOptions) {
        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 (taskId == null) {
            throw new IllegalArgumentException("Parameter taskId 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(taskTerminateOptions);
        Integer timeout = null;
        if (taskTerminateOptions != null) {
            timeout = taskTerminateOptions.timeout();
        }
        UUID clientRequestId = null;
        if (taskTerminateOptions != null) {
            clientRequestId = taskTerminateOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (taskTerminateOptions != null) {
            returnClientRequestId = taskTerminateOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (taskTerminateOptions != null) {
            ocpDate = taskTerminateOptions.ocpDate();
        }
        String ifMatch = null;
        if (taskTerminateOptions != null) {
            ifMatch = taskTerminateOptions.ifMatch();
        }
        String ifNoneMatch = null;
        if (taskTerminateOptions != null) {
            ifNoneMatch = taskTerminateOptions.ifNoneMatch();
        }
        DateTime ifModifiedSince = null;
        if (taskTerminateOptions != null) {
            ifModifiedSince = taskTerminateOptions.ifModifiedSince();
        }
        DateTime ifUnmodifiedSince = null;
        if (taskTerminateOptions != null) {
            ifUnmodifiedSince = taskTerminateOptions.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.terminate(jobId, taskId, 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, TaskTerminateHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, TaskTerminateHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, TaskTerminateHeaders> clientResponse = terminateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Reactivates a Task, allowing it to run again even if its retry count has been exhausted.
     * Reactivation makes a Task eligible to be retried again up to its maximum retry count. The Task's state is changed to active. As the Task is no longer in the completed state, any previous exit code or failure information is no longer available after reactivation. Each time a Task is reactivated, its retry count is reset to 0. Reactivation will fail for Tasks that are not completed or that previously completed successfully (with an exit code of 0). Additionally, it will fail if the Job has completed (or is terminating or deleting).
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to reactivate.
     * @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 reactivate(String jobId, String taskId) {
        reactivateWithServiceResponseAsync(jobId, taskId).toBlocking().single().body();
    }

    /**
     * Reactivates a Task, allowing it to run again even if its retry count has been exhausted.
     * Reactivation makes a Task eligible to be retried again up to its maximum retry count. The Task's state is changed to active. As the Task is no longer in the completed state, any previous exit code or failure information is no longer available after reactivation. Each time a Task is reactivated, its retry count is reset to 0. Reactivation will fail for Tasks that are not completed or that previously completed successfully (with an exit code of 0). Additionally, it will fail if the Job has completed (or is terminating or deleting).
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to reactivate.
     * @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> reactivateAsync(String jobId, String taskId, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(reactivateWithServiceResponseAsync(jobId, taskId), serviceCallback);
    }

    /**
     * Reactivates a Task, allowing it to run again even if its retry count has been exhausted.
     * Reactivation makes a Task eligible to be retried again up to its maximum retry count. The Task's state is changed to active. As the Task is no longer in the completed state, any previous exit code or failure information is no longer available after reactivation. Each time a Task is reactivated, its retry count is reset to 0. Reactivation will fail for Tasks that are not completed or that previously completed successfully (with an exit code of 0). Additionally, it will fail if the Job has completed (or is terminating or deleting).
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to reactivate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> reactivateAsync(String jobId, String taskId) {
        return reactivateWithServiceResponseAsync(jobId, taskId).map(new Func1<ServiceResponseWithHeaders<Void, TaskReactivateHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, TaskReactivateHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Reactivates a Task, allowing it to run again even if its retry count has been exhausted.
     * Reactivation makes a Task eligible to be retried again up to its maximum retry count. The Task's state is changed to active. As the Task is no longer in the completed state, any previous exit code or failure information is no longer available after reactivation. Each time a Task is reactivated, its retry count is reset to 0. Reactivation will fail for Tasks that are not completed or that previously completed successfully (with an exit code of 0). Additionally, it will fail if the Job has completed (or is terminating or deleting).
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to reactivate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, TaskReactivateHeaders>> reactivateWithServiceResponseAsync(String jobId, String taskId) {
        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 (taskId == null) {
            throw new IllegalArgumentException("Parameter taskId 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 TaskReactivateOptions taskReactivateOptions = 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.reactivate(jobId, taskId, 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, TaskReactivateHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, TaskReactivateHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, TaskReactivateHeaders> clientResponse = reactivateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Reactivates a Task, allowing it to run again even if its retry count has been exhausted.
     * Reactivation makes a Task eligible to be retried again up to its maximum retry count. The Task's state is changed to active. As the Task is no longer in the completed state, any previous exit code or failure information is no longer available after reactivation. Each time a Task is reactivated, its retry count is reset to 0. Reactivation will fail for Tasks that are not completed or that previously completed successfully (with an exit code of 0). Additionally, it will fail if the Job has completed (or is terminating or deleting).
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to reactivate.
     * @param taskReactivateOptions 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 reactivate(String jobId, String taskId, TaskReactivateOptions taskReactivateOptions) {
        reactivateWithServiceResponseAsync(jobId, taskId, taskReactivateOptions).toBlocking().single().body();
    }

    /**
     * Reactivates a Task, allowing it to run again even if its retry count has been exhausted.
     * Reactivation makes a Task eligible to be retried again up to its maximum retry count. The Task's state is changed to active. As the Task is no longer in the completed state, any previous exit code or failure information is no longer available after reactivation. Each time a Task is reactivated, its retry count is reset to 0. Reactivation will fail for Tasks that are not completed or that previously completed successfully (with an exit code of 0). Additionally, it will fail if the Job has completed (or is terminating or deleting).
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to reactivate.
     * @param taskReactivateOptions 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> reactivateAsync(String jobId, String taskId, TaskReactivateOptions taskReactivateOptions, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(reactivateWithServiceResponseAsync(jobId, taskId, taskReactivateOptions), serviceCallback);
    }

    /**
     * Reactivates a Task, allowing it to run again even if its retry count has been exhausted.
     * Reactivation makes a Task eligible to be retried again up to its maximum retry count. The Task's state is changed to active. As the Task is no longer in the completed state, any previous exit code or failure information is no longer available after reactivation. Each time a Task is reactivated, its retry count is reset to 0. Reactivation will fail for Tasks that are not completed or that previously completed successfully (with an exit code of 0). Additionally, it will fail if the Job has completed (or is terminating or deleting).
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to reactivate.
     * @param taskReactivateOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> reactivateAsync(String jobId, String taskId, TaskReactivateOptions taskReactivateOptions) {
        return reactivateWithServiceResponseAsync(jobId, taskId, taskReactivateOptions).map(new Func1<ServiceResponseWithHeaders<Void, TaskReactivateHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, TaskReactivateHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Reactivates a Task, allowing it to run again even if its retry count has been exhausted.
     * Reactivation makes a Task eligible to be retried again up to its maximum retry count. The Task's state is changed to active. As the Task is no longer in the completed state, any previous exit code or failure information is no longer available after reactivation. Each time a Task is reactivated, its retry count is reset to 0. Reactivation will fail for Tasks that are not completed or that previously completed successfully (with an exit code of 0). Additionally, it will fail if the Job has completed (or is terminating or deleting).
     *
     * @param jobId The ID of the Job containing the Task.
     * @param taskId The ID of the Task to reactivate.
     * @param taskReactivateOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, TaskReactivateHeaders>> reactivateWithServiceResponseAsync(String jobId, String taskId, TaskReactivateOptions taskReactivateOptions) {
        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 (taskId == null) {
            throw new IllegalArgumentException("Parameter taskId 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(taskReactivateOptions);
        Integer timeout = null;
        if (taskReactivateOptions != null) {
            timeout = taskReactivateOptions.timeout();
        }
        UUID clientRequestId = null;
        if (taskReactivateOptions != null) {
            clientRequestId = taskReactivateOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (taskReactivateOptions != null) {
            returnClientRequestId = taskReactivateOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (taskReactivateOptions != null) {
            ocpDate = taskReactivateOptions.ocpDate();
        }
        String ifMatch = null;
        if (taskReactivateOptions != null) {
            ifMatch = taskReactivateOptions.ifMatch();
        }
        String ifNoneMatch = null;
        if (taskReactivateOptions != null) {
            ifNoneMatch = taskReactivateOptions.ifNoneMatch();
        }
        DateTime ifModifiedSince = null;
        if (taskReactivateOptions != null) {
            ifModifiedSince = taskReactivateOptions.ifModifiedSince();
        }
        DateTime ifUnmodifiedSince = null;
        if (taskReactivateOptions != null) {
            ifUnmodifiedSince = taskReactivateOptions.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.reactivate(jobId, taskId, 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, TaskReactivateHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, TaskReactivateHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, TaskReactivateHeaders> clientResponse = reactivateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Lists all of the Tasks that are associated with the specified Job.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @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;CloudTask&gt; object if successful.
     */
    public PagedList<CloudTask> listNext(final String nextPageLink) {
        ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders> response = listNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<CloudTask>(response.body()) {
            @Override
            public Page<CloudTask> nextPage(String nextPageLink) {
                return listNextSinglePageAsync(nextPageLink, null).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists all of the Tasks that are associated with the specified Job.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @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<CloudTask>> listNextAsync(final String nextPageLink, final ServiceFuture<List<CloudTask>> serviceFuture, final ListOperationCallback<CloudTask> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>> call(String nextPageLink) {
                    return listNextSinglePageAsync(nextPageLink, null);
                }
            },
            serviceCallback);
    }

    /**
     * Lists all of the Tasks that are associated with the specified Job.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @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;CloudTask&gt; object
     */
    public Observable<Page<CloudTask>> listNextAsync(final String nextPageLink) {
        return listNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>, Page<CloudTask>>() {
                @Override
                public Page<CloudTask> call(ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists all of the Tasks that are associated with the specified Job.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @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;CloudTask&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>> listNextWithServiceResponseAsync(final String nextPageLink) {
        return listNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>, Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>> call(ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders> 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 Tasks that are associated with the specified Job.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CloudTask&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>> listNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        final TaskListNextOptions taskListNextOptions = 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<CloudTask>, TaskListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<CloudTask>, TaskListHeaders> result = listNextDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Lists all of the Tasks that are associated with the specified Job.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param taskListNextOptions 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;CloudTask&gt; object if successful.
     */
    public PagedList<CloudTask> listNext(final String nextPageLink, final TaskListNextOptions taskListNextOptions) {
        ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders> response = listNextSinglePageAsync(nextPageLink, taskListNextOptions).toBlocking().single();
        return new PagedList<CloudTask>(response.body()) {
            @Override
            public Page<CloudTask> nextPage(String nextPageLink) {
                return listNextSinglePageAsync(nextPageLink, taskListNextOptions).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists all of the Tasks that are associated with the specified Job.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param taskListNextOptions 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<CloudTask>> listNextAsync(final String nextPageLink, final TaskListNextOptions taskListNextOptions, final ServiceFuture<List<CloudTask>> serviceFuture, final ListOperationCallback<CloudTask> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listNextSinglePageAsync(nextPageLink, taskListNextOptions),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>> call(String nextPageLink) {
                    return listNextSinglePageAsync(nextPageLink, taskListNextOptions);
                }
            },
            serviceCallback);
    }

    /**
     * Lists all of the Tasks that are associated with the specified Job.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param taskListNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CloudTask&gt; object
     */
    public Observable<Page<CloudTask>> listNextAsync(final String nextPageLink, final TaskListNextOptions taskListNextOptions) {
        return listNextWithServiceResponseAsync(nextPageLink, taskListNextOptions)
            .map(new Func1<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>, Page<CloudTask>>() {
                @Override
                public Page<CloudTask> call(ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists all of the Tasks that are associated with the specified Job.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param taskListNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CloudTask&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>> listNextWithServiceResponseAsync(final String nextPageLink, final TaskListNextOptions taskListNextOptions) {
        return listNextSinglePageAsync(nextPageLink, taskListNextOptions)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>, Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>> call(ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listNextWithServiceResponseAsync(nextPageLink, taskListNextOptions));
                }
            });
    }

    /**
     * Lists all of the Tasks that are associated with the specified Job.
     * For multi-instance Tasks, information such as affinityId, executionInfo and nodeInfo refer to the primary Task. Use the list subtasks API to retrieve information about subtasks.
     *
    ServiceResponseWithHeaders<PageImpl<CloudTask>, TaskListHeaders> * @param nextPageLink The NextLink from the previous successful call to List operation.
    ServiceResponseWithHeaders<PageImpl<CloudTask>, TaskListHeaders> * @param taskListNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CloudTask&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>> listNextSinglePageAsync(final String nextPageLink, final TaskListNextOptions taskListNextOptions) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        Validator.validate(taskListNextOptions);
        UUID clientRequestId = null;
        if (taskListNextOptions != null) {
            clientRequestId = taskListNextOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (taskListNextOptions != null) {
            returnClientRequestId = taskListNextOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (taskListNextOptions != null) {
            ocpDate = taskListNextOptions.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<CloudTask>, TaskListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<CloudTask>, TaskListHeaders> result = listNextDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<CloudTask>, TaskListHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

}
