/**
 * 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.management.containerregistry.implementation;

import retrofit2.Retrofit;
import com.google.common.reflect.TypeToken;
import com.microsoft.azure.AzureServiceFuture;
import com.microsoft.azure.CloudException;
import com.microsoft.azure.ListOperationCallback;
import com.microsoft.azure.management.containerregistry.RunUpdateParameters;
import com.microsoft.azure.Page;
import com.microsoft.azure.PagedList;
import com.microsoft.rest.ServiceCallback;
import com.microsoft.rest.ServiceFuture;
import com.microsoft.rest.ServiceResponse;
import java.io.IOException;
import java.util.List;
import okhttp3.ResponseBody;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.PATCH;
import retrofit2.http.Path;
import retrofit2.http.POST;
import retrofit2.http.Query;
import retrofit2.http.Url;
import retrofit2.Response;
import rx.functions.Func1;
import rx.Observable;

/**
 * An instance of this class provides access to all the operations defined
 * in Runs.
 */
public class RunsInner {
    /** The Retrofit service to perform REST calls. */
    private RunsService service;
    /** The service client containing this operation class. */
    private ContainerRegistryManagementClientImpl client;

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

    /**
     * The interface defining all the services for Runs to be
     * used by Retrofit to perform actually REST calls.
     */
    interface RunsService {
        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.management.containerregistry.Runs list" })
        @GET("subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ContainerRegistry/registries/{registryName}/runs")
        Observable<Response<ResponseBody>> list(@Path("subscriptionId") String subscriptionId, @Path("resourceGroupName") String resourceGroupName, @Path("registryName") String registryName, @Query("api-version") String apiVersion, @Query("$filter") String filter, @Query("$top") Integer top, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.management.containerregistry.Runs get" })
        @GET("subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ContainerRegistry/registries/{registryName}/runs/{runId}")
        Observable<Response<ResponseBody>> get(@Path("subscriptionId") String subscriptionId, @Path("resourceGroupName") String resourceGroupName, @Path("registryName") String registryName, @Path("runId") String runId, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.management.containerregistry.Runs update" })
        @PATCH("subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ContainerRegistry/registries/{registryName}/runs/{runId}")
        Observable<Response<ResponseBody>> update(@Path("subscriptionId") String subscriptionId, @Path("resourceGroupName") String resourceGroupName, @Path("registryName") String registryName, @Path("runId") String runId, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body RunUpdateParameters runUpdateParameters, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.management.containerregistry.Runs beginUpdate" })
        @PATCH("subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ContainerRegistry/registries/{registryName}/runs/{runId}")
        Observable<Response<ResponseBody>> beginUpdate(@Path("subscriptionId") String subscriptionId, @Path("resourceGroupName") String resourceGroupName, @Path("registryName") String registryName, @Path("runId") String runId, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body RunUpdateParameters runUpdateParameters, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.management.containerregistry.Runs getLogSasUrl" })
        @POST("subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ContainerRegistry/registries/{registryName}/runs/{runId}/listLogSasUrl")
        Observable<Response<ResponseBody>> getLogSasUrl(@Path("subscriptionId") String subscriptionId, @Path("resourceGroupName") String resourceGroupName, @Path("registryName") String registryName, @Path("runId") String runId, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.management.containerregistry.Runs cancel" })
        @POST("subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ContainerRegistry/registries/{registryName}/runs/{runId}/cancel")
        Observable<Response<ResponseBody>> cancel(@Path("subscriptionId") String subscriptionId, @Path("resourceGroupName") String resourceGroupName, @Path("registryName") String registryName, @Path("runId") String runId, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.management.containerregistry.Runs beginCancel" })
        @POST("subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ContainerRegistry/registries/{registryName}/runs/{runId}/cancel")
        Observable<Response<ResponseBody>> beginCancel(@Path("subscriptionId") String subscriptionId, @Path("resourceGroupName") String resourceGroupName, @Path("registryName") String registryName, @Path("runId") String runId, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.management.containerregistry.Runs listNext" })
        @GET
        Observable<Response<ResponseBody>> listNext(@Url String nextUrl, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

    }

    /**
     * Gets all the runs for a registry.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws CloudException 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;RunInner&gt; object if successful.
     */
    public PagedList<RunInner> list(final String resourceGroupName, final String registryName) {
        ServiceResponse<Page<RunInner>> response = listSinglePageAsync(resourceGroupName, registryName).toBlocking().single();
        return new PagedList<RunInner>(response.body()) {
            @Override
            public Page<RunInner> nextPage(String nextPageLink) {
                return listNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Gets all the runs for a registry.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @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<RunInner>> listAsync(final String resourceGroupName, final String registryName, final ListOperationCallback<RunInner> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            listSinglePageAsync(resourceGroupName, registryName),
            new Func1<String, Observable<ServiceResponse<Page<RunInner>>>>() {
                @Override
                public Observable<ServiceResponse<Page<RunInner>>> call(String nextPageLink) {
                    return listNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Gets all the runs for a registry.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;RunInner&gt; object
     */
    public Observable<Page<RunInner>> listAsync(final String resourceGroupName, final String registryName) {
        return listWithServiceResponseAsync(resourceGroupName, registryName)
            .map(new Func1<ServiceResponse<Page<RunInner>>, Page<RunInner>>() {
                @Override
                public Page<RunInner> call(ServiceResponse<Page<RunInner>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Gets all the runs for a registry.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;RunInner&gt; object
     */
    public Observable<ServiceResponse<Page<RunInner>>> listWithServiceResponseAsync(final String resourceGroupName, final String registryName) {
        return listSinglePageAsync(resourceGroupName, registryName)
            .concatMap(new Func1<ServiceResponse<Page<RunInner>>, Observable<ServiceResponse<Page<RunInner>>>>() {
                @Override
                public Observable<ServiceResponse<Page<RunInner>>> call(ServiceResponse<Page<RunInner>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Gets all the runs for a registry.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;RunInner&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<RunInner>>> listSinglePageAsync(final String resourceGroupName, final String registryName) {
        if (this.client.subscriptionId() == null) {
            throw new IllegalArgumentException("Parameter this.client.subscriptionId() is required and cannot be null.");
        }
        if (resourceGroupName == null) {
            throw new IllegalArgumentException("Parameter resourceGroupName is required and cannot be null.");
        }
        if (registryName == null) {
            throw new IllegalArgumentException("Parameter registryName is required and cannot be null.");
        }
        final String apiVersion = "2018-09-01";
        final String filter = null;
        final Integer top = null;
        return service.list(this.client.subscriptionId(), resourceGroupName, registryName, apiVersion, filter, top, this.client.acceptLanguage(), this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<RunInner>>>>() {
                @Override
                public Observable<ServiceResponse<Page<RunInner>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<RunInner>> result = listDelegate(response);
                        return Observable.just(new ServiceResponse<Page<RunInner>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Gets all the runs for a registry.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param filter The runs filter to apply on the operation. Arithmetic operators are not supported. The allowed string function is 'contains'. All logical operators except 'Not', 'Has', 'All' are allowed.
     * @param top $top is supported for get list of runs, which limits the maximum number of runs to return.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws CloudException 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;RunInner&gt; object if successful.
     */
    public PagedList<RunInner> list(final String resourceGroupName, final String registryName, final String filter, final Integer top) {
        ServiceResponse<Page<RunInner>> response = listSinglePageAsync(resourceGroupName, registryName, filter, top).toBlocking().single();
        return new PagedList<RunInner>(response.body()) {
            @Override
            public Page<RunInner> nextPage(String nextPageLink) {
                return listNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Gets all the runs for a registry.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param filter The runs filter to apply on the operation. Arithmetic operators are not supported. The allowed string function is 'contains'. All logical operators except 'Not', 'Has', 'All' are allowed.
     * @param top $top is supported for get list of runs, which limits the maximum number of runs to return.
     * @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<RunInner>> listAsync(final String resourceGroupName, final String registryName, final String filter, final Integer top, final ListOperationCallback<RunInner> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            listSinglePageAsync(resourceGroupName, registryName, filter, top),
            new Func1<String, Observable<ServiceResponse<Page<RunInner>>>>() {
                @Override
                public Observable<ServiceResponse<Page<RunInner>>> call(String nextPageLink) {
                    return listNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Gets all the runs for a registry.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param filter The runs filter to apply on the operation. Arithmetic operators are not supported. The allowed string function is 'contains'. All logical operators except 'Not', 'Has', 'All' are allowed.
     * @param top $top is supported for get list of runs, which limits the maximum number of runs to return.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;RunInner&gt; object
     */
    public Observable<Page<RunInner>> listAsync(final String resourceGroupName, final String registryName, final String filter, final Integer top) {
        return listWithServiceResponseAsync(resourceGroupName, registryName, filter, top)
            .map(new Func1<ServiceResponse<Page<RunInner>>, Page<RunInner>>() {
                @Override
                public Page<RunInner> call(ServiceResponse<Page<RunInner>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Gets all the runs for a registry.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param filter The runs filter to apply on the operation. Arithmetic operators are not supported. The allowed string function is 'contains'. All logical operators except 'Not', 'Has', 'All' are allowed.
     * @param top $top is supported for get list of runs, which limits the maximum number of runs to return.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;RunInner&gt; object
     */
    public Observable<ServiceResponse<Page<RunInner>>> listWithServiceResponseAsync(final String resourceGroupName, final String registryName, final String filter, final Integer top) {
        return listSinglePageAsync(resourceGroupName, registryName, filter, top)
            .concatMap(new Func1<ServiceResponse<Page<RunInner>>, Observable<ServiceResponse<Page<RunInner>>>>() {
                @Override
                public Observable<ServiceResponse<Page<RunInner>>> call(ServiceResponse<Page<RunInner>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Gets all the runs for a registry.
     *
    ServiceResponse<PageImpl<RunInner>> * @param resourceGroupName The name of the resource group to which the container registry belongs.
    ServiceResponse<PageImpl<RunInner>> * @param registryName The name of the container registry.
    ServiceResponse<PageImpl<RunInner>> * @param filter The runs filter to apply on the operation. Arithmetic operators are not supported. The allowed string function is 'contains'. All logical operators except 'Not', 'Has', 'All' are allowed.
    ServiceResponse<PageImpl<RunInner>> * @param top $top is supported for get list of runs, which limits the maximum number of runs to return.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;RunInner&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<RunInner>>> listSinglePageAsync(final String resourceGroupName, final String registryName, final String filter, final Integer top) {
        if (this.client.subscriptionId() == null) {
            throw new IllegalArgumentException("Parameter this.client.subscriptionId() is required and cannot be null.");
        }
        if (resourceGroupName == null) {
            throw new IllegalArgumentException("Parameter resourceGroupName is required and cannot be null.");
        }
        if (registryName == null) {
            throw new IllegalArgumentException("Parameter registryName is required and cannot be null.");
        }
        final String apiVersion = "2018-09-01";
        return service.list(this.client.subscriptionId(), resourceGroupName, registryName, apiVersion, filter, top, this.client.acceptLanguage(), this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<RunInner>>>>() {
                @Override
                public Observable<ServiceResponse<Page<RunInner>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<RunInner>> result = listDelegate(response);
                        return Observable.just(new ServiceResponse<Page<RunInner>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<RunInner>> listDelegate(Response<ResponseBody> response) throws CloudException, IOException, IllegalArgumentException {
        return this.client.restClient().responseBuilderFactory().<PageImpl<RunInner>, CloudException>newInstance(this.client.serializerAdapter())
                .register(200, new TypeToken<PageImpl<RunInner>>() { }.getType())
                .registerError(CloudException.class)
                .build(response);
    }

    /**
     * Gets the detailed information for a given run.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws CloudException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the RunInner object if successful.
     */
    public RunInner get(String resourceGroupName, String registryName, String runId) {
        return getWithServiceResponseAsync(resourceGroupName, registryName, runId).toBlocking().single().body();
    }

    /**
     * Gets the detailed information for a given run.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @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<RunInner> getAsync(String resourceGroupName, String registryName, String runId, final ServiceCallback<RunInner> serviceCallback) {
        return ServiceFuture.fromResponse(getWithServiceResponseAsync(resourceGroupName, registryName, runId), serviceCallback);
    }

    /**
     * Gets the detailed information for a given run.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the RunInner object
     */
    public Observable<RunInner> getAsync(String resourceGroupName, String registryName, String runId) {
        return getWithServiceResponseAsync(resourceGroupName, registryName, runId).map(new Func1<ServiceResponse<RunInner>, RunInner>() {
            @Override
            public RunInner call(ServiceResponse<RunInner> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets the detailed information for a given run.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the RunInner object
     */
    public Observable<ServiceResponse<RunInner>> getWithServiceResponseAsync(String resourceGroupName, String registryName, String runId) {
        if (this.client.subscriptionId() == null) {
            throw new IllegalArgumentException("Parameter this.client.subscriptionId() is required and cannot be null.");
        }
        if (resourceGroupName == null) {
            throw new IllegalArgumentException("Parameter resourceGroupName is required and cannot be null.");
        }
        if (registryName == null) {
            throw new IllegalArgumentException("Parameter registryName is required and cannot be null.");
        }
        if (runId == null) {
            throw new IllegalArgumentException("Parameter runId is required and cannot be null.");
        }
        final String apiVersion = "2018-09-01";
        return service.get(this.client.subscriptionId(), resourceGroupName, registryName, runId, apiVersion, this.client.acceptLanguage(), this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<RunInner>>>() {
                @Override
                public Observable<ServiceResponse<RunInner>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<RunInner> clientResponse = getDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<RunInner> getDelegate(Response<ResponseBody> response) throws CloudException, IOException, IllegalArgumentException {
        return this.client.restClient().responseBuilderFactory().<RunInner, CloudException>newInstance(this.client.serializerAdapter())
                .register(200, new TypeToken<RunInner>() { }.getType())
                .registerError(CloudException.class)
                .build(response);
    }

    /**
     * Patch the run properties.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws CloudException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the RunInner object if successful.
     */
    public RunInner update(String resourceGroupName, String registryName, String runId) {
        return updateWithServiceResponseAsync(resourceGroupName, registryName, runId).toBlocking().last().body();
    }

    /**
     * Patch the run properties.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @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<RunInner> updateAsync(String resourceGroupName, String registryName, String runId, final ServiceCallback<RunInner> serviceCallback) {
        return ServiceFuture.fromResponse(updateWithServiceResponseAsync(resourceGroupName, registryName, runId), serviceCallback);
    }

    /**
     * Patch the run properties.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable for the request
     */
    public Observable<RunInner> updateAsync(String resourceGroupName, String registryName, String runId) {
        return updateWithServiceResponseAsync(resourceGroupName, registryName, runId).map(new Func1<ServiceResponse<RunInner>, RunInner>() {
            @Override
            public RunInner call(ServiceResponse<RunInner> response) {
                return response.body();
            }
        });
    }

    /**
     * Patch the run properties.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable for the request
     */
    public Observable<ServiceResponse<RunInner>> updateWithServiceResponseAsync(String resourceGroupName, String registryName, String runId) {
        if (this.client.subscriptionId() == null) {
            throw new IllegalArgumentException("Parameter this.client.subscriptionId() is required and cannot be null.");
        }
        if (resourceGroupName == null) {
            throw new IllegalArgumentException("Parameter resourceGroupName is required and cannot be null.");
        }
        if (registryName == null) {
            throw new IllegalArgumentException("Parameter registryName is required and cannot be null.");
        }
        if (runId == null) {
            throw new IllegalArgumentException("Parameter runId is required and cannot be null.");
        }
        final String apiVersion = "2018-09-01";
        final Boolean isArchiveEnabled = null;
        RunUpdateParameters runUpdateParameters = new RunUpdateParameters();
        runUpdateParameters.withIsArchiveEnabled(null);
        Observable<Response<ResponseBody>> observable = service.update(this.client.subscriptionId(), resourceGroupName, registryName, runId, apiVersion, this.client.acceptLanguage(), runUpdateParameters, this.client.userAgent());
        return client.getAzureClient().getPutOrPatchResultAsync(observable, new TypeToken<RunInner>() { }.getType());
    }
    /**
     * Patch the run properties.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @param isArchiveEnabled The value that indicates whether archiving is enabled or not.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws CloudException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the RunInner object if successful.
     */
    public RunInner update(String resourceGroupName, String registryName, String runId, Boolean isArchiveEnabled) {
        return updateWithServiceResponseAsync(resourceGroupName, registryName, runId, isArchiveEnabled).toBlocking().last().body();
    }

    /**
     * Patch the run properties.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @param isArchiveEnabled The value that indicates whether archiving is enabled or not.
     * @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<RunInner> updateAsync(String resourceGroupName, String registryName, String runId, Boolean isArchiveEnabled, final ServiceCallback<RunInner> serviceCallback) {
        return ServiceFuture.fromResponse(updateWithServiceResponseAsync(resourceGroupName, registryName, runId, isArchiveEnabled), serviceCallback);
    }

    /**
     * Patch the run properties.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @param isArchiveEnabled The value that indicates whether archiving is enabled or not.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable for the request
     */
    public Observable<RunInner> updateAsync(String resourceGroupName, String registryName, String runId, Boolean isArchiveEnabled) {
        return updateWithServiceResponseAsync(resourceGroupName, registryName, runId, isArchiveEnabled).map(new Func1<ServiceResponse<RunInner>, RunInner>() {
            @Override
            public RunInner call(ServiceResponse<RunInner> response) {
                return response.body();
            }
        });
    }

    /**
     * Patch the run properties.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @param isArchiveEnabled The value that indicates whether archiving is enabled or not.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable for the request
     */
    public Observable<ServiceResponse<RunInner>> updateWithServiceResponseAsync(String resourceGroupName, String registryName, String runId, Boolean isArchiveEnabled) {
        if (this.client.subscriptionId() == null) {
            throw new IllegalArgumentException("Parameter this.client.subscriptionId() is required and cannot be null.");
        }
        if (resourceGroupName == null) {
            throw new IllegalArgumentException("Parameter resourceGroupName is required and cannot be null.");
        }
        if (registryName == null) {
            throw new IllegalArgumentException("Parameter registryName is required and cannot be null.");
        }
        if (runId == null) {
            throw new IllegalArgumentException("Parameter runId is required and cannot be null.");
        }
        final String apiVersion = "2018-09-01";
        RunUpdateParameters runUpdateParameters = new RunUpdateParameters();
        runUpdateParameters.withIsArchiveEnabled(isArchiveEnabled);
        Observable<Response<ResponseBody>> observable = service.update(this.client.subscriptionId(), resourceGroupName, registryName, runId, apiVersion, this.client.acceptLanguage(), runUpdateParameters, this.client.userAgent());
        return client.getAzureClient().getPutOrPatchResultAsync(observable, new TypeToken<RunInner>() { }.getType());
    }

    /**
     * Patch the run properties.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws CloudException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the RunInner object if successful.
     */
    public RunInner beginUpdate(String resourceGroupName, String registryName, String runId) {
        return beginUpdateWithServiceResponseAsync(resourceGroupName, registryName, runId).toBlocking().single().body();
    }

    /**
     * Patch the run properties.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @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<RunInner> beginUpdateAsync(String resourceGroupName, String registryName, String runId, final ServiceCallback<RunInner> serviceCallback) {
        return ServiceFuture.fromResponse(beginUpdateWithServiceResponseAsync(resourceGroupName, registryName, runId), serviceCallback);
    }

    /**
     * Patch the run properties.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the RunInner object
     */
    public Observable<RunInner> beginUpdateAsync(String resourceGroupName, String registryName, String runId) {
        return beginUpdateWithServiceResponseAsync(resourceGroupName, registryName, runId).map(new Func1<ServiceResponse<RunInner>, RunInner>() {
            @Override
            public RunInner call(ServiceResponse<RunInner> response) {
                return response.body();
            }
        });
    }

    /**
     * Patch the run properties.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the RunInner object
     */
    public Observable<ServiceResponse<RunInner>> beginUpdateWithServiceResponseAsync(String resourceGroupName, String registryName, String runId) {
        if (this.client.subscriptionId() == null) {
            throw new IllegalArgumentException("Parameter this.client.subscriptionId() is required and cannot be null.");
        }
        if (resourceGroupName == null) {
            throw new IllegalArgumentException("Parameter resourceGroupName is required and cannot be null.");
        }
        if (registryName == null) {
            throw new IllegalArgumentException("Parameter registryName is required and cannot be null.");
        }
        if (runId == null) {
            throw new IllegalArgumentException("Parameter runId is required and cannot be null.");
        }
        final String apiVersion = "2018-09-01";
        final Boolean isArchiveEnabled = null;
        RunUpdateParameters runUpdateParameters = new RunUpdateParameters();
        runUpdateParameters.withIsArchiveEnabled(null);
        return service.beginUpdate(this.client.subscriptionId(), resourceGroupName, registryName, runId, apiVersion, this.client.acceptLanguage(), runUpdateParameters, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<RunInner>>>() {
                @Override
                public Observable<ServiceResponse<RunInner>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<RunInner> clientResponse = beginUpdateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Patch the run properties.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @param isArchiveEnabled The value that indicates whether archiving is enabled or not.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws CloudException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the RunInner object if successful.
     */
    public RunInner beginUpdate(String resourceGroupName, String registryName, String runId, Boolean isArchiveEnabled) {
        return beginUpdateWithServiceResponseAsync(resourceGroupName, registryName, runId, isArchiveEnabled).toBlocking().single().body();
    }

    /**
     * Patch the run properties.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @param isArchiveEnabled The value that indicates whether archiving is enabled or not.
     * @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<RunInner> beginUpdateAsync(String resourceGroupName, String registryName, String runId, Boolean isArchiveEnabled, final ServiceCallback<RunInner> serviceCallback) {
        return ServiceFuture.fromResponse(beginUpdateWithServiceResponseAsync(resourceGroupName, registryName, runId, isArchiveEnabled), serviceCallback);
    }

    /**
     * Patch the run properties.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @param isArchiveEnabled The value that indicates whether archiving is enabled or not.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the RunInner object
     */
    public Observable<RunInner> beginUpdateAsync(String resourceGroupName, String registryName, String runId, Boolean isArchiveEnabled) {
        return beginUpdateWithServiceResponseAsync(resourceGroupName, registryName, runId, isArchiveEnabled).map(new Func1<ServiceResponse<RunInner>, RunInner>() {
            @Override
            public RunInner call(ServiceResponse<RunInner> response) {
                return response.body();
            }
        });
    }

    /**
     * Patch the run properties.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @param isArchiveEnabled The value that indicates whether archiving is enabled or not.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the RunInner object
     */
    public Observable<ServiceResponse<RunInner>> beginUpdateWithServiceResponseAsync(String resourceGroupName, String registryName, String runId, Boolean isArchiveEnabled) {
        if (this.client.subscriptionId() == null) {
            throw new IllegalArgumentException("Parameter this.client.subscriptionId() is required and cannot be null.");
        }
        if (resourceGroupName == null) {
            throw new IllegalArgumentException("Parameter resourceGroupName is required and cannot be null.");
        }
        if (registryName == null) {
            throw new IllegalArgumentException("Parameter registryName is required and cannot be null.");
        }
        if (runId == null) {
            throw new IllegalArgumentException("Parameter runId is required and cannot be null.");
        }
        final String apiVersion = "2018-09-01";
        RunUpdateParameters runUpdateParameters = new RunUpdateParameters();
        runUpdateParameters.withIsArchiveEnabled(isArchiveEnabled);
        return service.beginUpdate(this.client.subscriptionId(), resourceGroupName, registryName, runId, apiVersion, this.client.acceptLanguage(), runUpdateParameters, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<RunInner>>>() {
                @Override
                public Observable<ServiceResponse<RunInner>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<RunInner> clientResponse = beginUpdateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<RunInner> beginUpdateDelegate(Response<ResponseBody> response) throws CloudException, IOException, IllegalArgumentException {
        return this.client.restClient().responseBuilderFactory().<RunInner, CloudException>newInstance(this.client.serializerAdapter())
                .register(200, new TypeToken<RunInner>() { }.getType())
                .register(201, new TypeToken<RunInner>() { }.getType())
                .registerError(CloudException.class)
                .build(response);
    }

    /**
     * Gets a link to download the run logs.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws CloudException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the RunGetLogResultInner object if successful.
     */
    public RunGetLogResultInner getLogSasUrl(String resourceGroupName, String registryName, String runId) {
        return getLogSasUrlWithServiceResponseAsync(resourceGroupName, registryName, runId).toBlocking().single().body();
    }

    /**
     * Gets a link to download the run logs.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @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<RunGetLogResultInner> getLogSasUrlAsync(String resourceGroupName, String registryName, String runId, final ServiceCallback<RunGetLogResultInner> serviceCallback) {
        return ServiceFuture.fromResponse(getLogSasUrlWithServiceResponseAsync(resourceGroupName, registryName, runId), serviceCallback);
    }

    /**
     * Gets a link to download the run logs.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the RunGetLogResultInner object
     */
    public Observable<RunGetLogResultInner> getLogSasUrlAsync(String resourceGroupName, String registryName, String runId) {
        return getLogSasUrlWithServiceResponseAsync(resourceGroupName, registryName, runId).map(new Func1<ServiceResponse<RunGetLogResultInner>, RunGetLogResultInner>() {
            @Override
            public RunGetLogResultInner call(ServiceResponse<RunGetLogResultInner> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets a link to download the run logs.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the RunGetLogResultInner object
     */
    public Observable<ServiceResponse<RunGetLogResultInner>> getLogSasUrlWithServiceResponseAsync(String resourceGroupName, String registryName, String runId) {
        if (this.client.subscriptionId() == null) {
            throw new IllegalArgumentException("Parameter this.client.subscriptionId() is required and cannot be null.");
        }
        if (resourceGroupName == null) {
            throw new IllegalArgumentException("Parameter resourceGroupName is required and cannot be null.");
        }
        if (registryName == null) {
            throw new IllegalArgumentException("Parameter registryName is required and cannot be null.");
        }
        if (runId == null) {
            throw new IllegalArgumentException("Parameter runId is required and cannot be null.");
        }
        final String apiVersion = "2018-09-01";
        return service.getLogSasUrl(this.client.subscriptionId(), resourceGroupName, registryName, runId, apiVersion, this.client.acceptLanguage(), this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<RunGetLogResultInner>>>() {
                @Override
                public Observable<ServiceResponse<RunGetLogResultInner>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<RunGetLogResultInner> clientResponse = getLogSasUrlDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<RunGetLogResultInner> getLogSasUrlDelegate(Response<ResponseBody> response) throws CloudException, IOException, IllegalArgumentException {
        return this.client.restClient().responseBuilderFactory().<RunGetLogResultInner, CloudException>newInstance(this.client.serializerAdapter())
                .register(200, new TypeToken<RunGetLogResultInner>() { }.getType())
                .registerError(CloudException.class)
                .build(response);
    }

    /**
     * Cancel an existing run.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws CloudException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     */
    public void cancel(String resourceGroupName, String registryName, String runId) {
        cancelWithServiceResponseAsync(resourceGroupName, registryName, runId).toBlocking().last().body();
    }

    /**
     * Cancel an existing run.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @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> cancelAsync(String resourceGroupName, String registryName, String runId, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromResponse(cancelWithServiceResponseAsync(resourceGroupName, registryName, runId), serviceCallback);
    }

    /**
     * Cancel an existing run.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable for the request
     */
    public Observable<Void> cancelAsync(String resourceGroupName, String registryName, String runId) {
        return cancelWithServiceResponseAsync(resourceGroupName, registryName, runId).map(new Func1<ServiceResponse<Void>, Void>() {
            @Override
            public Void call(ServiceResponse<Void> response) {
                return response.body();
            }
        });
    }

    /**
     * Cancel an existing run.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable for the request
     */
    public Observable<ServiceResponse<Void>> cancelWithServiceResponseAsync(String resourceGroupName, String registryName, String runId) {
        if (this.client.subscriptionId() == null) {
            throw new IllegalArgumentException("Parameter this.client.subscriptionId() is required and cannot be null.");
        }
        if (resourceGroupName == null) {
            throw new IllegalArgumentException("Parameter resourceGroupName is required and cannot be null.");
        }
        if (registryName == null) {
            throw new IllegalArgumentException("Parameter registryName is required and cannot be null.");
        }
        if (runId == null) {
            throw new IllegalArgumentException("Parameter runId is required and cannot be null.");
        }
        final String apiVersion = "2018-09-01";
        Observable<Response<ResponseBody>> observable = service.cancel(this.client.subscriptionId(), resourceGroupName, registryName, runId, apiVersion, this.client.acceptLanguage(), this.client.userAgent());
        return client.getAzureClient().getPostOrDeleteResultAsync(observable, new TypeToken<Void>() { }.getType());
    }

    /**
     * Cancel an existing run.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws CloudException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     */
    public void beginCancel(String resourceGroupName, String registryName, String runId) {
        beginCancelWithServiceResponseAsync(resourceGroupName, registryName, runId).toBlocking().single().body();
    }

    /**
     * Cancel an existing run.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @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> beginCancelAsync(String resourceGroupName, String registryName, String runId, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromResponse(beginCancelWithServiceResponseAsync(resourceGroupName, registryName, runId), serviceCallback);
    }

    /**
     * Cancel an existing run.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponse} object if successful.
     */
    public Observable<Void> beginCancelAsync(String resourceGroupName, String registryName, String runId) {
        return beginCancelWithServiceResponseAsync(resourceGroupName, registryName, runId).map(new Func1<ServiceResponse<Void>, Void>() {
            @Override
            public Void call(ServiceResponse<Void> response) {
                return response.body();
            }
        });
    }

    /**
     * Cancel an existing run.
     *
     * @param resourceGroupName The name of the resource group to which the container registry belongs.
     * @param registryName The name of the container registry.
     * @param runId The run ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponse} object if successful.
     */
    public Observable<ServiceResponse<Void>> beginCancelWithServiceResponseAsync(String resourceGroupName, String registryName, String runId) {
        if (this.client.subscriptionId() == null) {
            throw new IllegalArgumentException("Parameter this.client.subscriptionId() is required and cannot be null.");
        }
        if (resourceGroupName == null) {
            throw new IllegalArgumentException("Parameter resourceGroupName is required and cannot be null.");
        }
        if (registryName == null) {
            throw new IllegalArgumentException("Parameter registryName is required and cannot be null.");
        }
        if (runId == null) {
            throw new IllegalArgumentException("Parameter runId is required and cannot be null.");
        }
        final String apiVersion = "2018-09-01";
        return service.beginCancel(this.client.subscriptionId(), resourceGroupName, registryName, runId, apiVersion, this.client.acceptLanguage(), this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Void>>>() {
                @Override
                public Observable<ServiceResponse<Void>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<Void> clientResponse = beginCancelDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<Void> beginCancelDelegate(Response<ResponseBody> response) throws CloudException, IOException, IllegalArgumentException {
        return this.client.restClient().responseBuilderFactory().<Void, CloudException>newInstance(this.client.serializerAdapter())
                .register(200, new TypeToken<Void>() { }.getType())
                .register(202, new TypeToken<Void>() { }.getType())
                .registerError(CloudException.class)
                .build(response);
    }

    /**
     * Gets all the runs for a registry.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws CloudException 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;RunInner&gt; object if successful.
     */
    public PagedList<RunInner> listNext(final String nextPageLink) {
        ServiceResponse<Page<RunInner>> response = listNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<RunInner>(response.body()) {
            @Override
            public Page<RunInner> nextPage(String nextPageLink) {
                return listNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Gets all the runs for a registry.
     *
     * @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<RunInner>> listNextAsync(final String nextPageLink, final ServiceFuture<List<RunInner>> serviceFuture, final ListOperationCallback<RunInner> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            listNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponse<Page<RunInner>>>>() {
                @Override
                public Observable<ServiceResponse<Page<RunInner>>> call(String nextPageLink) {
                    return listNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Gets all the runs for a registry.
     *
     * @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;RunInner&gt; object
     */
    public Observable<Page<RunInner>> listNextAsync(final String nextPageLink) {
        return listNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponse<Page<RunInner>>, Page<RunInner>>() {
                @Override
                public Page<RunInner> call(ServiceResponse<Page<RunInner>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Gets all the runs for a registry.
     *
     * @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;RunInner&gt; object
     */
    public Observable<ServiceResponse<Page<RunInner>>> listNextWithServiceResponseAsync(final String nextPageLink) {
        return listNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponse<Page<RunInner>>, Observable<ServiceResponse<Page<RunInner>>>>() {
                @Override
                public Observable<ServiceResponse<Page<RunInner>>> call(ServiceResponse<Page<RunInner>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Gets all the runs for a registry.
     *
    ServiceResponse<PageImpl<RunInner>> * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;RunInner&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<RunInner>>> listNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.listNext(nextUrl, this.client.acceptLanguage(), this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<RunInner>>>>() {
                @Override
                public Observable<ServiceResponse<Page<RunInner>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<RunInner>> result = listNextDelegate(response);
                        return Observable.just(new ServiceResponse<Page<RunInner>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<RunInner>> listNextDelegate(Response<ResponseBody> response) throws CloudException, IOException, IllegalArgumentException {
        return this.client.restClient().responseBuilderFactory().<PageImpl<RunInner>, CloudException>newInstance(this.client.serializerAdapter())
                .register(200, new TypeToken<PageImpl<RunInner>>() { }.getType())
                .registerError(CloudException.class)
                .build(response);
    }

}
