/**
 * 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.cognitiveservices.language.luis.authoring.implementation;

import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.ListAppsOptionalParameter;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.ImportMethodAppsOptionalParameter;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.DeleteAppsOptionalParameter;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.UpdateSettingsOptionalParameter;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.ImportV2AppAppsOptionalParameter;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.ImportLuFormatAppsOptionalParameter;
import retrofit2.Retrofit;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.Apps;
import com.google.common.base.Joiner;
import com.google.common.reflect.TypeToken;
import com.microsoft.azure.CloudException;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.ApplicationCreateObject;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.ApplicationInfoResponse;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.ApplicationPublishObject;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.ApplicationSettings;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.ApplicationSettingUpdateObject;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.ApplicationUpdateObject;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.AvailableCulture;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.ErrorResponseException;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.LuisApp;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.LuisAppV2;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.OperationStatus;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.PersonalAssistantsResponse;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.PrebuiltDomain;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.PrebuiltDomainCreateObject;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.ProductionOrStagingEndpointInfo;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.PublishSettings;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.PublishSettingUpdateObject;
import com.microsoft.rest.ServiceCallback;
import com.microsoft.rest.ServiceFuture;
import com.microsoft.rest.ServiceResponse;
import com.microsoft.rest.Validator;
import java.io.InputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import okhttp3.ResponseBody;
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.Streaming;
import retrofit2.Response;
import rx.functions.Func1;
import rx.Observable;

/**
 * An instance of this class provides access to all the operations defined
 * in Apps.
 */
public class AppsImpl implements Apps {
    /** The Retrofit service to perform REST calls. */
    private AppsService service;
    /** The service client containing this operation class. */
    private LUISAuthoringClientImpl client;

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

    /**
     * The interface defining all the services for Apps to be
     * used by Retrofit to perform actually REST calls.
     */
    interface AppsService {
        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.cognitiveservices.language.luis.authoring.Apps add" })
        @POST("apps/")
        Observable<Response<ResponseBody>> add(@Body ApplicationCreateObject applicationCreateObject, @Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps list" })
        @GET("apps/")
        Observable<Response<ResponseBody>> list(@Query("skip") Integer skip, @Query("take") Integer take, @Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps importMethod" })
        @POST("apps/import")
        Observable<Response<ResponseBody>> importMethod(@Query("appName") String appName, @Body LuisApp luisApp, @Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps listCortanaEndpoints" })
        @GET("apps/assistants")
        Observable<Response<ResponseBody>> listCortanaEndpoints(@Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps listDomains" })
        @GET("apps/domains")
        Observable<Response<ResponseBody>> listDomains(@Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps listUsageScenarios" })
        @GET("apps/usagescenarios")
        Observable<Response<ResponseBody>> listUsageScenarios(@Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps listSupportedCultures" })
        @GET("apps/cultures")
        Observable<Response<ResponseBody>> listSupportedCultures(@Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps downloadQueryLogs" })
        @GET("apps/{appId}/querylogs")
        @Streaming
        Observable<Response<ResponseBody>> downloadQueryLogs(@Path("appId") UUID appId, @Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps get" })
        @GET("apps/{appId}")
        Observable<Response<ResponseBody>> get(@Path("appId") UUID appId, @Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps update" })
        @PUT("apps/{appId}")
        Observable<Response<ResponseBody>> update(@Path("appId") UUID appId, @Body ApplicationUpdateObject applicationUpdateObject, @Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps delete" })
        @HTTP(path = "apps/{appId}", method = "DELETE", hasBody = true)
        Observable<Response<ResponseBody>> delete(@Path("appId") UUID appId, @Query("force") Boolean force, @Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps publish" })
        @POST("apps/{appId}/publish")
        Observable<Response<ResponseBody>> publish(@Path("appId") UUID appId, @Body ApplicationPublishObject applicationPublishObject, @Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps getSettings" })
        @GET("apps/{appId}/settings")
        Observable<Response<ResponseBody>> getSettings(@Path("appId") UUID appId, @Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps updateSettings" })
        @PUT("apps/{appId}/settings")
        Observable<Response<ResponseBody>> updateSettings(@Path("appId") UUID appId, @Header("accept-language") String acceptLanguage, @Body ApplicationSettingUpdateObject applicationSettingUpdateObject, @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.cognitiveservices.language.luis.authoring.Apps getPublishSettings" })
        @GET("apps/{appId}/publishsettings")
        Observable<Response<ResponseBody>> getPublishSettings(@Path("appId") UUID appId, @Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps updatePublishSettings" })
        @PUT("apps/{appId}/publishsettings")
        Observable<Response<ResponseBody>> updatePublishSettings(@Path("appId") UUID appId, @Body PublishSettingUpdateObject publishSettingUpdateObject, @Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps listEndpoints" })
        @GET("apps/{appId}/endpoints")
        Observable<Response<ResponseBody>> listEndpoints(@Path("appId") UUID appId, @Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps listAvailableCustomPrebuiltDomains" })
        @GET("apps/customprebuiltdomains")
        Observable<Response<ResponseBody>> listAvailableCustomPrebuiltDomains(@Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps addCustomPrebuiltDomain" })
        @POST("apps/customprebuiltdomains")
        Observable<Response<ResponseBody>> addCustomPrebuiltDomain(@Body PrebuiltDomainCreateObject prebuiltDomainCreateObject, @Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps listAvailableCustomPrebuiltDomainsForCulture" })
        @GET("apps/customprebuiltdomains/{culture}")
        Observable<Response<ResponseBody>> listAvailableCustomPrebuiltDomainsForCulture(@Path("culture") String culture, @Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps packagePublishedApplicationAsGzip" })
        @GET("package/{appId}/slot/{slotName}/gzip")
        @Streaming
        Observable<Response<ResponseBody>> packagePublishedApplicationAsGzip(@Path("appId") UUID appId, @Path("slotName") String slotName, @Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps packageTrainedApplicationAsGzip" })
        @GET("package/{appId}/versions/{versionId}/gzip")
        @Streaming
        Observable<Response<ResponseBody>> packageTrainedApplicationAsGzip(@Path("appId") UUID appId, @Path("versionId") String versionId, @Header("accept-language") String acceptLanguage, @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.cognitiveservices.language.luis.authoring.Apps importV2App" })
        @POST("apps/import")
        Observable<Response<ResponseBody>> importV2App(@Query("appName") String appName, @Body LuisAppV2 luisAppV2, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: text/plain", "x-ms-logging-context: com.microsoft.azure.cognitiveservices.language.luis.authoring.Apps importLuFormat" })
        @POST("apps/import")
        Observable<Response<ResponseBody>> importLuFormat(@Query("appName") String appName, @Body String luisAppLu, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

    }

    /**
     * Creates a new LUIS app.
     *
     * @param applicationCreateObject An application containing Name, Description (optional), Culture, Usage Scenario (optional), Domain (optional) and initial version ID (optional) of the application. Default value for the version ID is "0.1". Note: the culture cannot be changed after the app is created.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the UUID object if successful.
     */
    public UUID add(ApplicationCreateObject applicationCreateObject) {
        return addWithServiceResponseAsync(applicationCreateObject).toBlocking().single().body();
    }

    /**
     * Creates a new LUIS app.
     *
     * @param applicationCreateObject An application containing Name, Description (optional), Culture, Usage Scenario (optional), Domain (optional) and initial version ID (optional) of the application. Default value for the version ID is "0.1". Note: the culture cannot be changed after the app is created.
     * @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<UUID> addAsync(ApplicationCreateObject applicationCreateObject, final ServiceCallback<UUID> serviceCallback) {
        return ServiceFuture.fromResponse(addWithServiceResponseAsync(applicationCreateObject), serviceCallback);
    }

    /**
     * Creates a new LUIS app.
     *
     * @param applicationCreateObject An application containing Name, Description (optional), Culture, Usage Scenario (optional), Domain (optional) and initial version ID (optional) of the application. Default value for the version ID is "0.1". Note: the culture cannot be changed after the app is created.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the UUID object
     */
    public Observable<UUID> addAsync(ApplicationCreateObject applicationCreateObject) {
        return addWithServiceResponseAsync(applicationCreateObject).map(new Func1<ServiceResponse<UUID>, UUID>() {
            @Override
            public UUID call(ServiceResponse<UUID> response) {
                return response.body();
            }
        });
    }

    /**
     * Creates a new LUIS app.
     *
     * @param applicationCreateObject An application containing Name, Description (optional), Culture, Usage Scenario (optional), Domain (optional) and initial version ID (optional) of the application. Default value for the version ID is "0.1". Note: the culture cannot be changed after the app is created.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the UUID object
     */
    public Observable<ServiceResponse<UUID>> addWithServiceResponseAsync(ApplicationCreateObject applicationCreateObject) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (applicationCreateObject == null) {
            throw new IllegalArgumentException("Parameter applicationCreateObject is required and cannot be null.");
        }
        Validator.validate(applicationCreateObject);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.add(applicationCreateObject, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<UUID>>>() {
                @Override
                public Observable<ServiceResponse<UUID>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<UUID> clientResponse = addDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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


    /**
     * Lists all of the user's applications.
     *
     * @param listOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the List&lt;ApplicationInfoResponse&gt; object if successful.
     */
    public List<ApplicationInfoResponse> list(ListAppsOptionalParameter listOptionalParameter) {
        return listWithServiceResponseAsync(listOptionalParameter).toBlocking().single().body();
    }

    /**
     * Lists all of the user's applications.
     *
     * @param listOptionalParameter the object representing the optional parameters to be set before calling this API
     * @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<ApplicationInfoResponse>> listAsync(ListAppsOptionalParameter listOptionalParameter, final ServiceCallback<List<ApplicationInfoResponse>> serviceCallback) {
        return ServiceFuture.fromResponse(listWithServiceResponseAsync(listOptionalParameter), serviceCallback);
    }

    /**
     * Lists all of the user's applications.
     *
     * @param listOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;ApplicationInfoResponse&gt; object
     */
    public Observable<List<ApplicationInfoResponse>> listAsync(ListAppsOptionalParameter listOptionalParameter) {
        return listWithServiceResponseAsync(listOptionalParameter).map(new Func1<ServiceResponse<List<ApplicationInfoResponse>>, List<ApplicationInfoResponse>>() {
            @Override
            public List<ApplicationInfoResponse> call(ServiceResponse<List<ApplicationInfoResponse>> response) {
                return response.body();
            }
        });
    }

    /**
     * Lists all of the user's applications.
     *
     * @param listOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;ApplicationInfoResponse&gt; object
     */
    public Observable<ServiceResponse<List<ApplicationInfoResponse>>> listWithServiceResponseAsync(ListAppsOptionalParameter listOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        final Integer skip = listOptionalParameter != null ? listOptionalParameter.skip() : null;
        final Integer take = listOptionalParameter != null ? listOptionalParameter.take() : null;

        return listWithServiceResponseAsync(skip, take);
    }

    /**
     * Lists all of the user's applications.
     *
     * @param skip The number of entries to skip. Default value is 0.
     * @param take The number of entries to return. Maximum page size is 500. Default is 100.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;ApplicationInfoResponse&gt; object
     */
    public Observable<ServiceResponse<List<ApplicationInfoResponse>>> listWithServiceResponseAsync(Integer skip, Integer take) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.list(skip, take, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<List<ApplicationInfoResponse>>>>() {
                @Override
                public Observable<ServiceResponse<List<ApplicationInfoResponse>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<List<ApplicationInfoResponse>> clientResponse = listDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public AppsListParameters list() {
        return new AppsListParameters(this);
    }

    /**
     * Internal class implementing AppsListDefinition.
     */
    class AppsListParameters implements AppsListDefinition {
        private AppsImpl parent;
        private Integer skip;
        private Integer take;

        /**
         * Constructor.
         * @param parent the parent object.
         */
        AppsListParameters(AppsImpl parent) {
            this.parent = parent;
        }

        @Override
        public AppsListParameters withSkip(Integer skip) {
            this.skip = skip;
            return this;
        }

        @Override
        public AppsListParameters withTake(Integer take) {
            this.take = take;
            return this;
        }

        @Override
        public List<ApplicationInfoResponse> execute() {
        return listWithServiceResponseAsync(skip, take).toBlocking().single().body();
    }

        @Override
        public Observable<List<ApplicationInfoResponse>> executeAsync() {
            return listWithServiceResponseAsync(skip, take).map(new Func1<ServiceResponse<List<ApplicationInfoResponse>>, List<ApplicationInfoResponse>>() {
                @Override
                public List<ApplicationInfoResponse> call(ServiceResponse<List<ApplicationInfoResponse>> response) {
                    return response.body();
                }
            });
        }
    }


    /**
     * Imports an application to LUIS, the application's structure is included in the request body.
     *
     * @param luisApp A LUIS application structure.
     * @param importMethodOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the UUID object if successful.
     */
    public UUID importMethod(LuisApp luisApp, ImportMethodAppsOptionalParameter importMethodOptionalParameter) {
        return importMethodWithServiceResponseAsync(luisApp, importMethodOptionalParameter).toBlocking().single().body();
    }

    /**
     * Imports an application to LUIS, the application's structure is included in the request body.
     *
     * @param luisApp A LUIS application structure.
     * @param importMethodOptionalParameter the object representing the optional parameters to be set before calling this API
     * @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<UUID> importMethodAsync(LuisApp luisApp, ImportMethodAppsOptionalParameter importMethodOptionalParameter, final ServiceCallback<UUID> serviceCallback) {
        return ServiceFuture.fromResponse(importMethodWithServiceResponseAsync(luisApp, importMethodOptionalParameter), serviceCallback);
    }

    /**
     * Imports an application to LUIS, the application's structure is included in the request body.
     *
     * @param luisApp A LUIS application structure.
     * @param importMethodOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the UUID object
     */
    public Observable<UUID> importMethodAsync(LuisApp luisApp, ImportMethodAppsOptionalParameter importMethodOptionalParameter) {
        return importMethodWithServiceResponseAsync(luisApp, importMethodOptionalParameter).map(new Func1<ServiceResponse<UUID>, UUID>() {
            @Override
            public UUID call(ServiceResponse<UUID> response) {
                return response.body();
            }
        });
    }

    /**
     * Imports an application to LUIS, the application's structure is included in the request body.
     *
     * @param luisApp A LUIS application structure.
     * @param importMethodOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the UUID object
     */
    public Observable<ServiceResponse<UUID>> importMethodWithServiceResponseAsync(LuisApp luisApp, ImportMethodAppsOptionalParameter importMethodOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (luisApp == null) {
            throw new IllegalArgumentException("Parameter luisApp is required and cannot be null.");
        }
        Validator.validate(luisApp);
        final String appName = importMethodOptionalParameter != null ? importMethodOptionalParameter.appName() : null;

        return importMethodWithServiceResponseAsync(luisApp, appName);
    }

    /**
     * Imports an application to LUIS, the application's structure is included in the request body.
     *
     * @param luisApp A LUIS application structure.
     * @param appName The application name to create. If not specified, the application name will be read from the imported object. If the application name already exists, an error is returned.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the UUID object
     */
    public Observable<ServiceResponse<UUID>> importMethodWithServiceResponseAsync(LuisApp luisApp, String appName) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (luisApp == null) {
            throw new IllegalArgumentException("Parameter luisApp is required and cannot be null.");
        }
        Validator.validate(luisApp);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.importMethod(appName, luisApp, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<UUID>>>() {
                @Override
                public Observable<ServiceResponse<UUID>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<UUID> clientResponse = importMethodDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public AppsImportMethodParameters importMethod() {
        return new AppsImportMethodParameters(this);
    }

    /**
     * Internal class implementing AppsImportMethodDefinition.
     */
    class AppsImportMethodParameters implements AppsImportMethodDefinition {
        private AppsImpl parent;
        private LuisApp luisApp;
        private String appName;

        /**
         * Constructor.
         * @param parent the parent object.
         */
        AppsImportMethodParameters(AppsImpl parent) {
            this.parent = parent;
        }

        @Override
        public AppsImportMethodParameters withLuisApp(LuisApp luisApp) {
            this.luisApp = luisApp;
            return this;
        }

        @Override
        public AppsImportMethodParameters withAppName(String appName) {
            this.appName = appName;
            return this;
        }

        @Override
        public UUID execute() {
        return importMethodWithServiceResponseAsync(luisApp, appName).toBlocking().single().body();
    }

        @Override
        public Observable<UUID> executeAsync() {
            return importMethodWithServiceResponseAsync(luisApp, appName).map(new Func1<ServiceResponse<UUID>, UUID>() {
                @Override
                public UUID call(ServiceResponse<UUID> response) {
                    return response.body();
                }
            });
        }
    }

    /**
     * Gets the endpoint URLs for the prebuilt Cortana applications.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PersonalAssistantsResponse object if successful.
     */
    public PersonalAssistantsResponse listCortanaEndpoints() {
        return listCortanaEndpointsWithServiceResponseAsync().toBlocking().single().body();
    }

    /**
     * Gets the endpoint URLs for the prebuilt Cortana applications.
     *
     * @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<PersonalAssistantsResponse> listCortanaEndpointsAsync(final ServiceCallback<PersonalAssistantsResponse> serviceCallback) {
        return ServiceFuture.fromResponse(listCortanaEndpointsWithServiceResponseAsync(), serviceCallback);
    }

    /**
     * Gets the endpoint URLs for the prebuilt Cortana applications.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PersonalAssistantsResponse object
     */
    public Observable<PersonalAssistantsResponse> listCortanaEndpointsAsync() {
        return listCortanaEndpointsWithServiceResponseAsync().map(new Func1<ServiceResponse<PersonalAssistantsResponse>, PersonalAssistantsResponse>() {
            @Override
            public PersonalAssistantsResponse call(ServiceResponse<PersonalAssistantsResponse> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets the endpoint URLs for the prebuilt Cortana applications.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PersonalAssistantsResponse object
     */
    public Observable<ServiceResponse<PersonalAssistantsResponse>> listCortanaEndpointsWithServiceResponseAsync() {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.listCortanaEndpoints(this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<PersonalAssistantsResponse>>>() {
                @Override
                public Observable<ServiceResponse<PersonalAssistantsResponse>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PersonalAssistantsResponse> clientResponse = listCortanaEndpointsDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Gets the available application domains.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the List&lt;String&gt; object if successful.
     */
    public List<String> listDomains() {
        return listDomainsWithServiceResponseAsync().toBlocking().single().body();
    }

    /**
     * Gets the available application domains.
     *
     * @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<String>> listDomainsAsync(final ServiceCallback<List<String>> serviceCallback) {
        return ServiceFuture.fromResponse(listDomainsWithServiceResponseAsync(), serviceCallback);
    }

    /**
     * Gets the available application domains.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;String&gt; object
     */
    public Observable<List<String>> listDomainsAsync() {
        return listDomainsWithServiceResponseAsync().map(new Func1<ServiceResponse<List<String>>, List<String>>() {
            @Override
            public List<String> call(ServiceResponse<List<String>> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets the available application domains.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;String&gt; object
     */
    public Observable<ServiceResponse<List<String>>> listDomainsWithServiceResponseAsync() {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.listDomains(this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<List<String>>>>() {
                @Override
                public Observable<ServiceResponse<List<String>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<List<String>> clientResponse = listDomainsDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Gets the application available usage scenarios.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the List&lt;String&gt; object if successful.
     */
    public List<String> listUsageScenarios() {
        return listUsageScenariosWithServiceResponseAsync().toBlocking().single().body();
    }

    /**
     * Gets the application available usage scenarios.
     *
     * @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<String>> listUsageScenariosAsync(final ServiceCallback<List<String>> serviceCallback) {
        return ServiceFuture.fromResponse(listUsageScenariosWithServiceResponseAsync(), serviceCallback);
    }

    /**
     * Gets the application available usage scenarios.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;String&gt; object
     */
    public Observable<List<String>> listUsageScenariosAsync() {
        return listUsageScenariosWithServiceResponseAsync().map(new Func1<ServiceResponse<List<String>>, List<String>>() {
            @Override
            public List<String> call(ServiceResponse<List<String>> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets the application available usage scenarios.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;String&gt; object
     */
    public Observable<ServiceResponse<List<String>>> listUsageScenariosWithServiceResponseAsync() {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.listUsageScenarios(this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<List<String>>>>() {
                @Override
                public Observable<ServiceResponse<List<String>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<List<String>> clientResponse = listUsageScenariosDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Gets a list of supported cultures. Cultures are equivalent to the written language and locale. For example,"en-us" represents the U.S. variation of English.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the List&lt;AvailableCulture&gt; object if successful.
     */
    public List<AvailableCulture> listSupportedCultures() {
        return listSupportedCulturesWithServiceResponseAsync().toBlocking().single().body();
    }

    /**
     * Gets a list of supported cultures. Cultures are equivalent to the written language and locale. For example,"en-us" represents the U.S. variation of English.
     *
     * @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<AvailableCulture>> listSupportedCulturesAsync(final ServiceCallback<List<AvailableCulture>> serviceCallback) {
        return ServiceFuture.fromResponse(listSupportedCulturesWithServiceResponseAsync(), serviceCallback);
    }

    /**
     * Gets a list of supported cultures. Cultures are equivalent to the written language and locale. For example,"en-us" represents the U.S. variation of English.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;AvailableCulture&gt; object
     */
    public Observable<List<AvailableCulture>> listSupportedCulturesAsync() {
        return listSupportedCulturesWithServiceResponseAsync().map(new Func1<ServiceResponse<List<AvailableCulture>>, List<AvailableCulture>>() {
            @Override
            public List<AvailableCulture> call(ServiceResponse<List<AvailableCulture>> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets a list of supported cultures. Cultures are equivalent to the written language and locale. For example,"en-us" represents the U.S. variation of English.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;AvailableCulture&gt; object
     */
    public Observable<ServiceResponse<List<AvailableCulture>>> listSupportedCulturesWithServiceResponseAsync() {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.listSupportedCultures(this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<List<AvailableCulture>>>>() {
                @Override
                public Observable<ServiceResponse<List<AvailableCulture>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<List<AvailableCulture>> clientResponse = listSupportedCulturesDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Gets the logs of the past month's endpoint queries for the application.
     *
     * @param appId The application 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 InputStream object if successful.
     */
    public InputStream downloadQueryLogs(UUID appId) {
        return downloadQueryLogsWithServiceResponseAsync(appId).toBlocking().single().body();
    }

    /**
     * Gets the logs of the past month's endpoint queries for the application.
     *
     * @param appId The application 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<InputStream> downloadQueryLogsAsync(UUID appId, final ServiceCallback<InputStream> serviceCallback) {
        return ServiceFuture.fromResponse(downloadQueryLogsWithServiceResponseAsync(appId), serviceCallback);
    }

    /**
     * Gets the logs of the past month's endpoint queries for the application.
     *
     * @param appId The application ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the InputStream object
     */
    public Observable<InputStream> downloadQueryLogsAsync(UUID appId) {
        return downloadQueryLogsWithServiceResponseAsync(appId).map(new Func1<ServiceResponse<InputStream>, InputStream>() {
            @Override
            public InputStream call(ServiceResponse<InputStream> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets the logs of the past month's endpoint queries for the application.
     *
     * @param appId The application ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the InputStream object
     */
    public Observable<ServiceResponse<InputStream>> downloadQueryLogsWithServiceResponseAsync(UUID appId) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (appId == null) {
            throw new IllegalArgumentException("Parameter appId is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.downloadQueryLogs(appId, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<InputStream>>>() {
                @Override
                public Observable<ServiceResponse<InputStream>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<InputStream> clientResponse = downloadQueryLogsDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Gets the application info.
     *
     * @param appId The application ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the ApplicationInfoResponse object if successful.
     */
    public ApplicationInfoResponse get(UUID appId) {
        return getWithServiceResponseAsync(appId).toBlocking().single().body();
    }

    /**
     * Gets the application info.
     *
     * @param appId The application 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<ApplicationInfoResponse> getAsync(UUID appId, final ServiceCallback<ApplicationInfoResponse> serviceCallback) {
        return ServiceFuture.fromResponse(getWithServiceResponseAsync(appId), serviceCallback);
    }

    /**
     * Gets the application info.
     *
     * @param appId The application ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the ApplicationInfoResponse object
     */
    public Observable<ApplicationInfoResponse> getAsync(UUID appId) {
        return getWithServiceResponseAsync(appId).map(new Func1<ServiceResponse<ApplicationInfoResponse>, ApplicationInfoResponse>() {
            @Override
            public ApplicationInfoResponse call(ServiceResponse<ApplicationInfoResponse> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets the application info.
     *
     * @param appId The application ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the ApplicationInfoResponse object
     */
    public Observable<ServiceResponse<ApplicationInfoResponse>> getWithServiceResponseAsync(UUID appId) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (appId == null) {
            throw new IllegalArgumentException("Parameter appId is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.get(appId, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<ApplicationInfoResponse>>>() {
                @Override
                public Observable<ServiceResponse<ApplicationInfoResponse>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<ApplicationInfoResponse> clientResponse = getDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Updates the name or description of the application.
     *
     * @param appId The application ID.
     * @param applicationUpdateObject A model containing Name and Description of the application.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the OperationStatus object if successful.
     */
    public OperationStatus update(UUID appId, ApplicationUpdateObject applicationUpdateObject) {
        return updateWithServiceResponseAsync(appId, applicationUpdateObject).toBlocking().single().body();
    }

    /**
     * Updates the name or description of the application.
     *
     * @param appId The application ID.
     * @param applicationUpdateObject A model containing Name and Description of the application.
     * @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<OperationStatus> updateAsync(UUID appId, ApplicationUpdateObject applicationUpdateObject, final ServiceCallback<OperationStatus> serviceCallback) {
        return ServiceFuture.fromResponse(updateWithServiceResponseAsync(appId, applicationUpdateObject), serviceCallback);
    }

    /**
     * Updates the name or description of the application.
     *
     * @param appId The application ID.
     * @param applicationUpdateObject A model containing Name and Description of the application.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the OperationStatus object
     */
    public Observable<OperationStatus> updateAsync(UUID appId, ApplicationUpdateObject applicationUpdateObject) {
        return updateWithServiceResponseAsync(appId, applicationUpdateObject).map(new Func1<ServiceResponse<OperationStatus>, OperationStatus>() {
            @Override
            public OperationStatus call(ServiceResponse<OperationStatus> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates the name or description of the application.
     *
     * @param appId The application ID.
     * @param applicationUpdateObject A model containing Name and Description of the application.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the OperationStatus object
     */
    public Observable<ServiceResponse<OperationStatus>> updateWithServiceResponseAsync(UUID appId, ApplicationUpdateObject applicationUpdateObject) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (appId == null) {
            throw new IllegalArgumentException("Parameter appId is required and cannot be null.");
        }
        if (applicationUpdateObject == null) {
            throw new IllegalArgumentException("Parameter applicationUpdateObject is required and cannot be null.");
        }
        Validator.validate(applicationUpdateObject);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.update(appId, applicationUpdateObject, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<OperationStatus>>>() {
                @Override
                public Observable<ServiceResponse<OperationStatus>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<OperationStatus> clientResponse = updateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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


    /**
     * Deletes an application.
     *
     * @param appId The application ID.
     * @param deleteOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the OperationStatus object if successful.
     */
    public OperationStatus delete(UUID appId, DeleteAppsOptionalParameter deleteOptionalParameter) {
        return deleteWithServiceResponseAsync(appId, deleteOptionalParameter).toBlocking().single().body();
    }

    /**
     * Deletes an application.
     *
     * @param appId The application ID.
     * @param deleteOptionalParameter the object representing the optional parameters to be set before calling this API
     * @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<OperationStatus> deleteAsync(UUID appId, DeleteAppsOptionalParameter deleteOptionalParameter, final ServiceCallback<OperationStatus> serviceCallback) {
        return ServiceFuture.fromResponse(deleteWithServiceResponseAsync(appId, deleteOptionalParameter), serviceCallback);
    }

    /**
     * Deletes an application.
     *
     * @param appId The application ID.
     * @param deleteOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the OperationStatus object
     */
    public Observable<OperationStatus> deleteAsync(UUID appId, DeleteAppsOptionalParameter deleteOptionalParameter) {
        return deleteWithServiceResponseAsync(appId, deleteOptionalParameter).map(new Func1<ServiceResponse<OperationStatus>, OperationStatus>() {
            @Override
            public OperationStatus call(ServiceResponse<OperationStatus> response) {
                return response.body();
            }
        });
    }

    /**
     * Deletes an application.
     *
     * @param appId The application ID.
     * @param deleteOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the OperationStatus object
     */
    public Observable<ServiceResponse<OperationStatus>> deleteWithServiceResponseAsync(UUID appId, DeleteAppsOptionalParameter deleteOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (appId == null) {
            throw new IllegalArgumentException("Parameter appId is required and cannot be null.");
        }
        final Boolean force = deleteOptionalParameter != null ? deleteOptionalParameter.force() : null;

        return deleteWithServiceResponseAsync(appId, force);
    }

    /**
     * Deletes an application.
     *
     * @param appId The application ID.
     * @param force A flag to indicate whether to force an operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the OperationStatus object
     */
    public Observable<ServiceResponse<OperationStatus>> deleteWithServiceResponseAsync(UUID appId, Boolean force) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (appId == null) {
            throw new IllegalArgumentException("Parameter appId is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.delete(appId, force, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<OperationStatus>>>() {
                @Override
                public Observable<ServiceResponse<OperationStatus>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<OperationStatus> clientResponse = deleteDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public AppsDeleteParameters delete() {
        return new AppsDeleteParameters(this);
    }

    /**
     * Internal class implementing AppsDeleteDefinition.
     */
    class AppsDeleteParameters implements AppsDeleteDefinition {
        private AppsImpl parent;
        private UUID appId;
        private Boolean force;

        /**
         * Constructor.
         * @param parent the parent object.
         */
        AppsDeleteParameters(AppsImpl parent) {
            this.parent = parent;
        }

        @Override
        public AppsDeleteParameters withAppId(UUID appId) {
            this.appId = appId;
            return this;
        }

        @Override
        public AppsDeleteParameters withForce(Boolean force) {
            this.force = force;
            return this;
        }

        @Override
        public OperationStatus execute() {
        return deleteWithServiceResponseAsync(appId, force).toBlocking().single().body();
    }

        @Override
        public Observable<OperationStatus> executeAsync() {
            return deleteWithServiceResponseAsync(appId, force).map(new Func1<ServiceResponse<OperationStatus>, OperationStatus>() {
                @Override
                public OperationStatus call(ServiceResponse<OperationStatus> response) {
                    return response.body();
                }
            });
        }
    }

    /**
     * Publishes a specific version of the application.
     *
     * @param appId The application ID.
     * @param applicationPublishObject The application publish object. The region is the target region that the application is published to.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the ProductionOrStagingEndpointInfo object if successful.
     */
    public ProductionOrStagingEndpointInfo publish(UUID appId, ApplicationPublishObject applicationPublishObject) {
        return publishWithServiceResponseAsync(appId, applicationPublishObject).toBlocking().single().body();
    }

    /**
     * Publishes a specific version of the application.
     *
     * @param appId The application ID.
     * @param applicationPublishObject The application publish object. The region is the target region that the application is published to.
     * @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<ProductionOrStagingEndpointInfo> publishAsync(UUID appId, ApplicationPublishObject applicationPublishObject, final ServiceCallback<ProductionOrStagingEndpointInfo> serviceCallback) {
        return ServiceFuture.fromResponse(publishWithServiceResponseAsync(appId, applicationPublishObject), serviceCallback);
    }

    /**
     * Publishes a specific version of the application.
     *
     * @param appId The application ID.
     * @param applicationPublishObject The application publish object. The region is the target region that the application is published to.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the ProductionOrStagingEndpointInfo object
     */
    public Observable<ProductionOrStagingEndpointInfo> publishAsync(UUID appId, ApplicationPublishObject applicationPublishObject) {
        return publishWithServiceResponseAsync(appId, applicationPublishObject).map(new Func1<ServiceResponse<ProductionOrStagingEndpointInfo>, ProductionOrStagingEndpointInfo>() {
            @Override
            public ProductionOrStagingEndpointInfo call(ServiceResponse<ProductionOrStagingEndpointInfo> response) {
                return response.body();
            }
        });
    }

    /**
     * Publishes a specific version of the application.
     *
     * @param appId The application ID.
     * @param applicationPublishObject The application publish object. The region is the target region that the application is published to.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the ProductionOrStagingEndpointInfo object
     */
    public Observable<ServiceResponse<ProductionOrStagingEndpointInfo>> publishWithServiceResponseAsync(UUID appId, ApplicationPublishObject applicationPublishObject) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (appId == null) {
            throw new IllegalArgumentException("Parameter appId is required and cannot be null.");
        }
        if (applicationPublishObject == null) {
            throw new IllegalArgumentException("Parameter applicationPublishObject is required and cannot be null.");
        }
        Validator.validate(applicationPublishObject);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.publish(appId, applicationPublishObject, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<ProductionOrStagingEndpointInfo>>>() {
                @Override
                public Observable<ServiceResponse<ProductionOrStagingEndpointInfo>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<ProductionOrStagingEndpointInfo> clientResponse = publishDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Get the application settings including 'UseAllTrainingData'.
     *
     * @param appId The application ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the ApplicationSettings object if successful.
     */
    public ApplicationSettings getSettings(UUID appId) {
        return getSettingsWithServiceResponseAsync(appId).toBlocking().single().body();
    }

    /**
     * Get the application settings including 'UseAllTrainingData'.
     *
     * @param appId The application 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<ApplicationSettings> getSettingsAsync(UUID appId, final ServiceCallback<ApplicationSettings> serviceCallback) {
        return ServiceFuture.fromResponse(getSettingsWithServiceResponseAsync(appId), serviceCallback);
    }

    /**
     * Get the application settings including 'UseAllTrainingData'.
     *
     * @param appId The application ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the ApplicationSettings object
     */
    public Observable<ApplicationSettings> getSettingsAsync(UUID appId) {
        return getSettingsWithServiceResponseAsync(appId).map(new Func1<ServiceResponse<ApplicationSettings>, ApplicationSettings>() {
            @Override
            public ApplicationSettings call(ServiceResponse<ApplicationSettings> response) {
                return response.body();
            }
        });
    }

    /**
     * Get the application settings including 'UseAllTrainingData'.
     *
     * @param appId The application ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the ApplicationSettings object
     */
    public Observable<ServiceResponse<ApplicationSettings>> getSettingsWithServiceResponseAsync(UUID appId) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (appId == null) {
            throw new IllegalArgumentException("Parameter appId is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.getSettings(appId, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<ApplicationSettings>>>() {
                @Override
                public Observable<ServiceResponse<ApplicationSettings>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<ApplicationSettings> clientResponse = getSettingsDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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


    /**
     * Updates the application settings including 'UseAllTrainingData'.
     *
     * @param appId The application ID.
     * @param updateSettingsOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the OperationStatus object if successful.
     */
    public OperationStatus updateSettings(UUID appId, UpdateSettingsOptionalParameter updateSettingsOptionalParameter) {
        return updateSettingsWithServiceResponseAsync(appId, updateSettingsOptionalParameter).toBlocking().single().body();
    }

    /**
     * Updates the application settings including 'UseAllTrainingData'.
     *
     * @param appId The application ID.
     * @param updateSettingsOptionalParameter the object representing the optional parameters to be set before calling this API
     * @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<OperationStatus> updateSettingsAsync(UUID appId, UpdateSettingsOptionalParameter updateSettingsOptionalParameter, final ServiceCallback<OperationStatus> serviceCallback) {
        return ServiceFuture.fromResponse(updateSettingsWithServiceResponseAsync(appId, updateSettingsOptionalParameter), serviceCallback);
    }

    /**
     * Updates the application settings including 'UseAllTrainingData'.
     *
     * @param appId The application ID.
     * @param updateSettingsOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the OperationStatus object
     */
    public Observable<OperationStatus> updateSettingsAsync(UUID appId, UpdateSettingsOptionalParameter updateSettingsOptionalParameter) {
        return updateSettingsWithServiceResponseAsync(appId, updateSettingsOptionalParameter).map(new Func1<ServiceResponse<OperationStatus>, OperationStatus>() {
            @Override
            public OperationStatus call(ServiceResponse<OperationStatus> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates the application settings including 'UseAllTrainingData'.
     *
     * @param appId The application ID.
     * @param updateSettingsOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the OperationStatus object
     */
    public Observable<ServiceResponse<OperationStatus>> updateSettingsWithServiceResponseAsync(UUID appId, UpdateSettingsOptionalParameter updateSettingsOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (appId == null) {
            throw new IllegalArgumentException("Parameter appId is required and cannot be null.");
        }
        final boolean isPublic = updateSettingsOptionalParameter != null ? updateSettingsOptionalParameter.isPublic() : false;

        return updateSettingsWithServiceResponseAsync(appId, isPublic);
    }

    /**
     * Updates the application settings including 'UseAllTrainingData'.
     *
     * @param appId The application ID.
     * @param isPublic Setting your application as public allows other people to use your application's endpoint using their own keys.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the OperationStatus object
     */
    public Observable<ServiceResponse<OperationStatus>> updateSettingsWithServiceResponseAsync(UUID appId, boolean isPublic) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (appId == null) {
            throw new IllegalArgumentException("Parameter appId is required and cannot be null.");
        }
        ApplicationSettingUpdateObject applicationSettingUpdateObject = new ApplicationSettingUpdateObject();
        applicationSettingUpdateObject.withIsPublic(isPublic);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.updateSettings(appId, this.client.acceptLanguage(), applicationSettingUpdateObject, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<OperationStatus>>>() {
                @Override
                public Observable<ServiceResponse<OperationStatus>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<OperationStatus> clientResponse = updateSettingsDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public AppsUpdateSettingsParameters updateSettings() {
        return new AppsUpdateSettingsParameters(this);
    }

    /**
     * Internal class implementing AppsUpdateSettingsDefinition.
     */
    class AppsUpdateSettingsParameters implements AppsUpdateSettingsDefinition {
        private AppsImpl parent;
        private UUID appId;
        private boolean isPublic;

        /**
         * Constructor.
         * @param parent the parent object.
         */
        AppsUpdateSettingsParameters(AppsImpl parent) {
            this.parent = parent;
        }

        @Override
        public AppsUpdateSettingsParameters withAppId(UUID appId) {
            this.appId = appId;
            return this;
        }

        @Override
        public AppsUpdateSettingsParameters withIsPublic(boolean isPublic) {
            this.isPublic = isPublic;
            return this;
        }

        @Override
        public OperationStatus execute() {
        return updateSettingsWithServiceResponseAsync(appId, isPublic).toBlocking().single().body();
    }

        @Override
        public Observable<OperationStatus> executeAsync() {
            return updateSettingsWithServiceResponseAsync(appId, isPublic).map(new Func1<ServiceResponse<OperationStatus>, OperationStatus>() {
                @Override
                public OperationStatus call(ServiceResponse<OperationStatus> response) {
                    return response.body();
                }
            });
        }
    }

    /**
     * Get the application publish settings including 'UseAllTrainingData'.
     *
     * @param appId The application ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PublishSettings object if successful.
     */
    public PublishSettings getPublishSettings(UUID appId) {
        return getPublishSettingsWithServiceResponseAsync(appId).toBlocking().single().body();
    }

    /**
     * Get the application publish settings including 'UseAllTrainingData'.
     *
     * @param appId The application 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<PublishSettings> getPublishSettingsAsync(UUID appId, final ServiceCallback<PublishSettings> serviceCallback) {
        return ServiceFuture.fromResponse(getPublishSettingsWithServiceResponseAsync(appId), serviceCallback);
    }

    /**
     * Get the application publish settings including 'UseAllTrainingData'.
     *
     * @param appId The application ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PublishSettings object
     */
    public Observable<PublishSettings> getPublishSettingsAsync(UUID appId) {
        return getPublishSettingsWithServiceResponseAsync(appId).map(new Func1<ServiceResponse<PublishSettings>, PublishSettings>() {
            @Override
            public PublishSettings call(ServiceResponse<PublishSettings> response) {
                return response.body();
            }
        });
    }

    /**
     * Get the application publish settings including 'UseAllTrainingData'.
     *
     * @param appId The application ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PublishSettings object
     */
    public Observable<ServiceResponse<PublishSettings>> getPublishSettingsWithServiceResponseAsync(UUID appId) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (appId == null) {
            throw new IllegalArgumentException("Parameter appId is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.getPublishSettings(appId, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<PublishSettings>>>() {
                @Override
                public Observable<ServiceResponse<PublishSettings>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PublishSettings> clientResponse = getPublishSettingsDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Updates the application publish settings including 'UseAllTrainingData'.
     *
     * @param appId The application ID.
     * @param publishSettingUpdateObject An object containing the new publish application settings.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the OperationStatus object if successful.
     */
    public OperationStatus updatePublishSettings(UUID appId, PublishSettingUpdateObject publishSettingUpdateObject) {
        return updatePublishSettingsWithServiceResponseAsync(appId, publishSettingUpdateObject).toBlocking().single().body();
    }

    /**
     * Updates the application publish settings including 'UseAllTrainingData'.
     *
     * @param appId The application ID.
     * @param publishSettingUpdateObject An object containing the new publish application settings.
     * @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<OperationStatus> updatePublishSettingsAsync(UUID appId, PublishSettingUpdateObject publishSettingUpdateObject, final ServiceCallback<OperationStatus> serviceCallback) {
        return ServiceFuture.fromResponse(updatePublishSettingsWithServiceResponseAsync(appId, publishSettingUpdateObject), serviceCallback);
    }

    /**
     * Updates the application publish settings including 'UseAllTrainingData'.
     *
     * @param appId The application ID.
     * @param publishSettingUpdateObject An object containing the new publish application settings.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the OperationStatus object
     */
    public Observable<OperationStatus> updatePublishSettingsAsync(UUID appId, PublishSettingUpdateObject publishSettingUpdateObject) {
        return updatePublishSettingsWithServiceResponseAsync(appId, publishSettingUpdateObject).map(new Func1<ServiceResponse<OperationStatus>, OperationStatus>() {
            @Override
            public OperationStatus call(ServiceResponse<OperationStatus> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates the application publish settings including 'UseAllTrainingData'.
     *
     * @param appId The application ID.
     * @param publishSettingUpdateObject An object containing the new publish application settings.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the OperationStatus object
     */
    public Observable<ServiceResponse<OperationStatus>> updatePublishSettingsWithServiceResponseAsync(UUID appId, PublishSettingUpdateObject publishSettingUpdateObject) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (appId == null) {
            throw new IllegalArgumentException("Parameter appId is required and cannot be null.");
        }
        if (publishSettingUpdateObject == null) {
            throw new IllegalArgumentException("Parameter publishSettingUpdateObject is required and cannot be null.");
        }
        Validator.validate(publishSettingUpdateObject);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.updatePublishSettings(appId, publishSettingUpdateObject, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<OperationStatus>>>() {
                @Override
                public Observable<ServiceResponse<OperationStatus>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<OperationStatus> clientResponse = updatePublishSettingsDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Returns the available endpoint deployment regions and URLs.
     *
     * @param appId The application ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the Map&lt;String, String&gt; object if successful.
     */
    public Map<String, String> listEndpoints(UUID appId) {
        return listEndpointsWithServiceResponseAsync(appId).toBlocking().single().body();
    }

    /**
     * Returns the available endpoint deployment regions and URLs.
     *
     * @param appId The application 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<Map<String, String>> listEndpointsAsync(UUID appId, final ServiceCallback<Map<String, String>> serviceCallback) {
        return ServiceFuture.fromResponse(listEndpointsWithServiceResponseAsync(appId), serviceCallback);
    }

    /**
     * Returns the available endpoint deployment regions and URLs.
     *
     * @param appId The application ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the Map&lt;String, String&gt; object
     */
    public Observable<Map<String, String>> listEndpointsAsync(UUID appId) {
        return listEndpointsWithServiceResponseAsync(appId).map(new Func1<ServiceResponse<Map<String, String>>, Map<String, String>>() {
            @Override
            public Map<String, String> call(ServiceResponse<Map<String, String>> response) {
                return response.body();
            }
        });
    }

    /**
     * Returns the available endpoint deployment regions and URLs.
     *
     * @param appId The application ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the Map&lt;String, String&gt; object
     */
    public Observable<ServiceResponse<Map<String, String>>> listEndpointsWithServiceResponseAsync(UUID appId) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (appId == null) {
            throw new IllegalArgumentException("Parameter appId is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.listEndpoints(appId, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Map<String, String>>>>() {
                @Override
                public Observable<ServiceResponse<Map<String, String>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<Map<String, String>> clientResponse = listEndpointsDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Gets all the available custom prebuilt domains for all cultures.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the List&lt;PrebuiltDomain&gt; object if successful.
     */
    public List<PrebuiltDomain> listAvailableCustomPrebuiltDomains() {
        return listAvailableCustomPrebuiltDomainsWithServiceResponseAsync().toBlocking().single().body();
    }

    /**
     * Gets all the available custom prebuilt domains for all cultures.
     *
     * @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<PrebuiltDomain>> listAvailableCustomPrebuiltDomainsAsync(final ServiceCallback<List<PrebuiltDomain>> serviceCallback) {
        return ServiceFuture.fromResponse(listAvailableCustomPrebuiltDomainsWithServiceResponseAsync(), serviceCallback);
    }

    /**
     * Gets all the available custom prebuilt domains for all cultures.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;PrebuiltDomain&gt; object
     */
    public Observable<List<PrebuiltDomain>> listAvailableCustomPrebuiltDomainsAsync() {
        return listAvailableCustomPrebuiltDomainsWithServiceResponseAsync().map(new Func1<ServiceResponse<List<PrebuiltDomain>>, List<PrebuiltDomain>>() {
            @Override
            public List<PrebuiltDomain> call(ServiceResponse<List<PrebuiltDomain>> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets all the available custom prebuilt domains for all cultures.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;PrebuiltDomain&gt; object
     */
    public Observable<ServiceResponse<List<PrebuiltDomain>>> listAvailableCustomPrebuiltDomainsWithServiceResponseAsync() {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.listAvailableCustomPrebuiltDomains(this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<List<PrebuiltDomain>>>>() {
                @Override
                public Observable<ServiceResponse<List<PrebuiltDomain>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<List<PrebuiltDomain>> clientResponse = listAvailableCustomPrebuiltDomainsDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Adds a prebuilt domain along with its intent and entity models as a new application.
     *
     * @param prebuiltDomainCreateObject A prebuilt domain create object containing the name and culture of the domain.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the UUID object if successful.
     */
    public UUID addCustomPrebuiltDomain(PrebuiltDomainCreateObject prebuiltDomainCreateObject) {
        return addCustomPrebuiltDomainWithServiceResponseAsync(prebuiltDomainCreateObject).toBlocking().single().body();
    }

    /**
     * Adds a prebuilt domain along with its intent and entity models as a new application.
     *
     * @param prebuiltDomainCreateObject A prebuilt domain create object containing the name and culture of the domain.
     * @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<UUID> addCustomPrebuiltDomainAsync(PrebuiltDomainCreateObject prebuiltDomainCreateObject, final ServiceCallback<UUID> serviceCallback) {
        return ServiceFuture.fromResponse(addCustomPrebuiltDomainWithServiceResponseAsync(prebuiltDomainCreateObject), serviceCallback);
    }

    /**
     * Adds a prebuilt domain along with its intent and entity models as a new application.
     *
     * @param prebuiltDomainCreateObject A prebuilt domain create object containing the name and culture of the domain.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the UUID object
     */
    public Observable<UUID> addCustomPrebuiltDomainAsync(PrebuiltDomainCreateObject prebuiltDomainCreateObject) {
        return addCustomPrebuiltDomainWithServiceResponseAsync(prebuiltDomainCreateObject).map(new Func1<ServiceResponse<UUID>, UUID>() {
            @Override
            public UUID call(ServiceResponse<UUID> response) {
                return response.body();
            }
        });
    }

    /**
     * Adds a prebuilt domain along with its intent and entity models as a new application.
     *
     * @param prebuiltDomainCreateObject A prebuilt domain create object containing the name and culture of the domain.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the UUID object
     */
    public Observable<ServiceResponse<UUID>> addCustomPrebuiltDomainWithServiceResponseAsync(PrebuiltDomainCreateObject prebuiltDomainCreateObject) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (prebuiltDomainCreateObject == null) {
            throw new IllegalArgumentException("Parameter prebuiltDomainCreateObject is required and cannot be null.");
        }
        Validator.validate(prebuiltDomainCreateObject);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.addCustomPrebuiltDomain(prebuiltDomainCreateObject, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<UUID>>>() {
                @Override
                public Observable<ServiceResponse<UUID>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<UUID> clientResponse = addCustomPrebuiltDomainDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Gets all the available prebuilt domains for a specific culture.
     *
     * @param culture Culture.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the List&lt;PrebuiltDomain&gt; object if successful.
     */
    public List<PrebuiltDomain> listAvailableCustomPrebuiltDomainsForCulture(String culture) {
        return listAvailableCustomPrebuiltDomainsForCultureWithServiceResponseAsync(culture).toBlocking().single().body();
    }

    /**
     * Gets all the available prebuilt domains for a specific culture.
     *
     * @param culture Culture.
     * @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<PrebuiltDomain>> listAvailableCustomPrebuiltDomainsForCultureAsync(String culture, final ServiceCallback<List<PrebuiltDomain>> serviceCallback) {
        return ServiceFuture.fromResponse(listAvailableCustomPrebuiltDomainsForCultureWithServiceResponseAsync(culture), serviceCallback);
    }

    /**
     * Gets all the available prebuilt domains for a specific culture.
     *
     * @param culture Culture.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;PrebuiltDomain&gt; object
     */
    public Observable<List<PrebuiltDomain>> listAvailableCustomPrebuiltDomainsForCultureAsync(String culture) {
        return listAvailableCustomPrebuiltDomainsForCultureWithServiceResponseAsync(culture).map(new Func1<ServiceResponse<List<PrebuiltDomain>>, List<PrebuiltDomain>>() {
            @Override
            public List<PrebuiltDomain> call(ServiceResponse<List<PrebuiltDomain>> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets all the available prebuilt domains for a specific culture.
     *
     * @param culture Culture.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;PrebuiltDomain&gt; object
     */
    public Observable<ServiceResponse<List<PrebuiltDomain>>> listAvailableCustomPrebuiltDomainsForCultureWithServiceResponseAsync(String culture) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (culture == null) {
            throw new IllegalArgumentException("Parameter culture is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.listAvailableCustomPrebuiltDomainsForCulture(culture, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<List<PrebuiltDomain>>>>() {
                @Override
                public Observable<ServiceResponse<List<PrebuiltDomain>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<List<PrebuiltDomain>> clientResponse = listAvailableCustomPrebuiltDomainsForCultureDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * package - Gets published LUIS application package in binary stream GZip format.
     * Packages a published LUIS application as a GZip file to be used in the LUIS container.
     *
     * @param appId The application ID.
     * @param slotName The publishing slot name.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the InputStream object if successful.
     */
    public InputStream packagePublishedApplicationAsGzip(UUID appId, String slotName) {
        return packagePublishedApplicationAsGzipWithServiceResponseAsync(appId, slotName).toBlocking().single().body();
    }

    /**
     * package - Gets published LUIS application package in binary stream GZip format.
     * Packages a published LUIS application as a GZip file to be used in the LUIS container.
     *
     * @param appId The application ID.
     * @param slotName The publishing slot name.
     * @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<InputStream> packagePublishedApplicationAsGzipAsync(UUID appId, String slotName, final ServiceCallback<InputStream> serviceCallback) {
        return ServiceFuture.fromResponse(packagePublishedApplicationAsGzipWithServiceResponseAsync(appId, slotName), serviceCallback);
    }

    /**
     * package - Gets published LUIS application package in binary stream GZip format.
     * Packages a published LUIS application as a GZip file to be used in the LUIS container.
     *
     * @param appId The application ID.
     * @param slotName The publishing slot name.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the InputStream object
     */
    public Observable<InputStream> packagePublishedApplicationAsGzipAsync(UUID appId, String slotName) {
        return packagePublishedApplicationAsGzipWithServiceResponseAsync(appId, slotName).map(new Func1<ServiceResponse<InputStream>, InputStream>() {
            @Override
            public InputStream call(ServiceResponse<InputStream> response) {
                return response.body();
            }
        });
    }

    /**
     * package - Gets published LUIS application package in binary stream GZip format.
     * Packages a published LUIS application as a GZip file to be used in the LUIS container.
     *
     * @param appId The application ID.
     * @param slotName The publishing slot name.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the InputStream object
     */
    public Observable<ServiceResponse<InputStream>> packagePublishedApplicationAsGzipWithServiceResponseAsync(UUID appId, String slotName) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (appId == null) {
            throw new IllegalArgumentException("Parameter appId is required and cannot be null.");
        }
        if (slotName == null) {
            throw new IllegalArgumentException("Parameter slotName is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.packagePublishedApplicationAsGzip(appId, slotName, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<InputStream>>>() {
                @Override
                public Observable<ServiceResponse<InputStream>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<InputStream> clientResponse = packagePublishedApplicationAsGzipDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * package - Gets trained LUIS application package in binary stream GZip format.
     * Packages trained LUIS application as GZip file to be used in the LUIS container.
     *
     * @param appId The application ID.
     * @param versionId The version ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the InputStream object if successful.
     */
    public InputStream packageTrainedApplicationAsGzip(UUID appId, String versionId) {
        return packageTrainedApplicationAsGzipWithServiceResponseAsync(appId, versionId).toBlocking().single().body();
    }

    /**
     * package - Gets trained LUIS application package in binary stream GZip format.
     * Packages trained LUIS application as GZip file to be used in the LUIS container.
     *
     * @param appId The application ID.
     * @param versionId The version 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<InputStream> packageTrainedApplicationAsGzipAsync(UUID appId, String versionId, final ServiceCallback<InputStream> serviceCallback) {
        return ServiceFuture.fromResponse(packageTrainedApplicationAsGzipWithServiceResponseAsync(appId, versionId), serviceCallback);
    }

    /**
     * package - Gets trained LUIS application package in binary stream GZip format.
     * Packages trained LUIS application as GZip file to be used in the LUIS container.
     *
     * @param appId The application ID.
     * @param versionId The version ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the InputStream object
     */
    public Observable<InputStream> packageTrainedApplicationAsGzipAsync(UUID appId, String versionId) {
        return packageTrainedApplicationAsGzipWithServiceResponseAsync(appId, versionId).map(new Func1<ServiceResponse<InputStream>, InputStream>() {
            @Override
            public InputStream call(ServiceResponse<InputStream> response) {
                return response.body();
            }
        });
    }

    /**
     * package - Gets trained LUIS application package in binary stream GZip format.
     * Packages trained LUIS application as GZip file to be used in the LUIS container.
     *
     * @param appId The application ID.
     * @param versionId The version ID.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the InputStream object
     */
    public Observable<ServiceResponse<InputStream>> packageTrainedApplicationAsGzipWithServiceResponseAsync(UUID appId, String versionId) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (appId == null) {
            throw new IllegalArgumentException("Parameter appId is required and cannot be null.");
        }
        if (versionId == null) {
            throw new IllegalArgumentException("Parameter versionId is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.packageTrainedApplicationAsGzip(appId, versionId, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<InputStream>>>() {
                @Override
                public Observable<ServiceResponse<InputStream>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<InputStream> clientResponse = packageTrainedApplicationAsGzipDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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


    /**
     * Imports an application to LUIS, the application's structure is included in the request body.
     *
     * @param luisAppV2 A LUIS application structure.
     * @param importV2AppOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the UUID object if successful.
     */
    public UUID importV2App(LuisAppV2 luisAppV2, ImportV2AppAppsOptionalParameter importV2AppOptionalParameter) {
        return importV2AppWithServiceResponseAsync(luisAppV2, importV2AppOptionalParameter).toBlocking().single().body();
    }

    /**
     * Imports an application to LUIS, the application's structure is included in the request body.
     *
     * @param luisAppV2 A LUIS application structure.
     * @param importV2AppOptionalParameter the object representing the optional parameters to be set before calling this API
     * @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<UUID> importV2AppAsync(LuisAppV2 luisAppV2, ImportV2AppAppsOptionalParameter importV2AppOptionalParameter, final ServiceCallback<UUID> serviceCallback) {
        return ServiceFuture.fromResponse(importV2AppWithServiceResponseAsync(luisAppV2, importV2AppOptionalParameter), serviceCallback);
    }

    /**
     * Imports an application to LUIS, the application's structure is included in the request body.
     *
     * @param luisAppV2 A LUIS application structure.
     * @param importV2AppOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the UUID object
     */
    public Observable<UUID> importV2AppAsync(LuisAppV2 luisAppV2, ImportV2AppAppsOptionalParameter importV2AppOptionalParameter) {
        return importV2AppWithServiceResponseAsync(luisAppV2, importV2AppOptionalParameter).map(new Func1<ServiceResponse<UUID>, UUID>() {
            @Override
            public UUID call(ServiceResponse<UUID> response) {
                return response.body();
            }
        });
    }

    /**
     * Imports an application to LUIS, the application's structure is included in the request body.
     *
     * @param luisAppV2 A LUIS application structure.
     * @param importV2AppOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the UUID object
     */
    public Observable<ServiceResponse<UUID>> importV2AppWithServiceResponseAsync(LuisAppV2 luisAppV2, ImportV2AppAppsOptionalParameter importV2AppOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (luisAppV2 == null) {
            throw new IllegalArgumentException("Parameter luisAppV2 is required and cannot be null.");
        }
        Validator.validate(luisAppV2);
        final String appName = importV2AppOptionalParameter != null ? importV2AppOptionalParameter.appName() : null;

        return importV2AppWithServiceResponseAsync(luisAppV2, appName);
    }

    /**
     * Imports an application to LUIS, the application's structure is included in the request body.
     *
     * @param luisAppV2 A LUIS application structure.
     * @param appName The application name to create. If not specified, the application name will be read from the imported object. If the application name already exists, an error is returned.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the UUID object
     */
    public Observable<ServiceResponse<UUID>> importV2AppWithServiceResponseAsync(LuisAppV2 luisAppV2, String appName) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (luisAppV2 == null) {
            throw new IllegalArgumentException("Parameter luisAppV2 is required and cannot be null.");
        }
        Validator.validate(luisAppV2);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.importV2App(appName, luisAppV2, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<UUID>>>() {
                @Override
                public Observable<ServiceResponse<UUID>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<UUID> clientResponse = importV2AppDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public AppsImportV2AppParameters importV2App() {
        return new AppsImportV2AppParameters(this);
    }

    /**
     * Internal class implementing AppsImportV2AppDefinition.
     */
    class AppsImportV2AppParameters implements AppsImportV2AppDefinition {
        private AppsImpl parent;
        private LuisAppV2 luisAppV2;
        private String appName;

        /**
         * Constructor.
         * @param parent the parent object.
         */
        AppsImportV2AppParameters(AppsImpl parent) {
            this.parent = parent;
        }

        @Override
        public AppsImportV2AppParameters withLuisAppV2(LuisAppV2 luisAppV2) {
            this.luisAppV2 = luisAppV2;
            return this;
        }

        @Override
        public AppsImportV2AppParameters withAppName(String appName) {
            this.appName = appName;
            return this;
        }

        @Override
        public UUID execute() {
        return importV2AppWithServiceResponseAsync(luisAppV2, appName).toBlocking().single().body();
    }

        @Override
        public Observable<UUID> executeAsync() {
            return importV2AppWithServiceResponseAsync(luisAppV2, appName).map(new Func1<ServiceResponse<UUID>, UUID>() {
                @Override
                public UUID call(ServiceResponse<UUID> response) {
                    return response.body();
                }
            });
        }
    }


    /**
     * Imports an application to LUIS, the application's structure is included in the request body.
     *
     * @param luisAppLu A LUIS application structure.
     * @param importLuFormatOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the UUID object if successful.
     */
    public UUID importLuFormat(String luisAppLu, ImportLuFormatAppsOptionalParameter importLuFormatOptionalParameter) {
        return importLuFormatWithServiceResponseAsync(luisAppLu, importLuFormatOptionalParameter).toBlocking().single().body();
    }

    /**
     * Imports an application to LUIS, the application's structure is included in the request body.
     *
     * @param luisAppLu A LUIS application structure.
     * @param importLuFormatOptionalParameter the object representing the optional parameters to be set before calling this API
     * @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<UUID> importLuFormatAsync(String luisAppLu, ImportLuFormatAppsOptionalParameter importLuFormatOptionalParameter, final ServiceCallback<UUID> serviceCallback) {
        return ServiceFuture.fromResponse(importLuFormatWithServiceResponseAsync(luisAppLu, importLuFormatOptionalParameter), serviceCallback);
    }

    /**
     * Imports an application to LUIS, the application's structure is included in the request body.
     *
     * @param luisAppLu A LUIS application structure.
     * @param importLuFormatOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the UUID object
     */
    public Observable<UUID> importLuFormatAsync(String luisAppLu, ImportLuFormatAppsOptionalParameter importLuFormatOptionalParameter) {
        return importLuFormatWithServiceResponseAsync(luisAppLu, importLuFormatOptionalParameter).map(new Func1<ServiceResponse<UUID>, UUID>() {
            @Override
            public UUID call(ServiceResponse<UUID> response) {
                return response.body();
            }
        });
    }

    /**
     * Imports an application to LUIS, the application's structure is included in the request body.
     *
     * @param luisAppLu A LUIS application structure.
     * @param importLuFormatOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the UUID object
     */
    public Observable<ServiceResponse<UUID>> importLuFormatWithServiceResponseAsync(String luisAppLu, ImportLuFormatAppsOptionalParameter importLuFormatOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (luisAppLu == null) {
            throw new IllegalArgumentException("Parameter luisAppLu is required and cannot be null.");
        }
        final String appName = importLuFormatOptionalParameter != null ? importLuFormatOptionalParameter.appName() : null;

        return importLuFormatWithServiceResponseAsync(luisAppLu, appName);
    }

    /**
     * Imports an application to LUIS, the application's structure is included in the request body.
     *
     * @param luisAppLu A LUIS application structure.
     * @param appName The application name to create. If not specified, the application name will be read from the imported object. If the application name already exists, an error is returned.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the UUID object
     */
    public Observable<ServiceResponse<UUID>> importLuFormatWithServiceResponseAsync(String luisAppLu, String appName) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (luisAppLu == null) {
            throw new IllegalArgumentException("Parameter luisAppLu is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.importLuFormat(appName, luisAppLu, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<UUID>>>() {
                @Override
                public Observable<ServiceResponse<UUID>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<UUID> clientResponse = importLuFormatDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public AppsImportLuFormatParameters importLuFormat() {
        return new AppsImportLuFormatParameters(this);
    }

    /**
     * Internal class implementing AppsImportLuFormatDefinition.
     */
    class AppsImportLuFormatParameters implements AppsImportLuFormatDefinition {
        private AppsImpl parent;
        private String luisAppLu;
        private String appName;

        /**
         * Constructor.
         * @param parent the parent object.
         */
        AppsImportLuFormatParameters(AppsImpl parent) {
            this.parent = parent;
        }

        @Override
        public AppsImportLuFormatParameters withLuisAppLu(String luisAppLu) {
            this.luisAppLu = luisAppLu;
            return this;
        }

        @Override
        public AppsImportLuFormatParameters withAppName(String appName) {
            this.appName = appName;
            return this;
        }

        @Override
        public UUID execute() {
        return importLuFormatWithServiceResponseAsync(luisAppLu, appName).toBlocking().single().body();
    }

        @Override
        public Observable<UUID> executeAsync() {
            return importLuFormatWithServiceResponseAsync(luisAppLu, appName).map(new Func1<ServiceResponse<UUID>, UUID>() {
                @Override
                public UUID call(ServiceResponse<UUID> response) {
                    return response.body();
                }
            });
        }
    }

}
