/**
 * 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.vision.computervision.implementation;

import com.microsoft.azure.cognitiveservices.vision.computervision.models.ReadInStreamOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.TagImageInStreamOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.RecognizePrintedTextInStreamOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.AnalyzeImageByDomainInStreamOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.GenerateThumbnailInStreamOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.DetectObjectsInStreamOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.DescribeImageInStreamOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.GetAreaOfInterestInStreamOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.AnalyzeImageInStreamOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.ReadOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.GetAreaOfInterestOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.GenerateThumbnailOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.TagImageOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.RecognizePrintedTextOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.AnalyzeImageByDomainOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.DetectObjectsOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.DescribeImageOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.AnalyzeImageOptionalParameter;
import retrofit2.Retrofit;
import com.microsoft.azure.cognitiveservices.vision.computervision.ComputerVision;
import com.google.common.base.Joiner;
import com.google.common.reflect.TypeToken;
import com.microsoft.azure.CloudException;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.AreaOfInterestResult;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.ComputerVisionErrorResponseException;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.ComputerVisionOcrErrorException;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.DescriptionExclude;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.Details;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.DetectResult;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.DomainModelResults;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.ImageAnalysis;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.ImageDescription;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.ImageUrl;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.ListModelsResult;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.OcrDetectionLanguage;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.OcrLanguages;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.OcrResult;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.ReadHeaders;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.ReadInStreamHeaders;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.ReadOperationResult;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.TagResult;
import com.microsoft.azure.cognitiveservices.vision.computervision.models.VisualFeatureTypes;
import com.microsoft.rest.CollectionFormat;
import com.microsoft.rest.ServiceCallback;
import com.microsoft.rest.ServiceFuture;
import com.microsoft.rest.ServiceResponse;
import com.microsoft.rest.ServiceResponseWithHeaders;
import com.microsoft.rest.Validator;
import java.io.InputStream;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.Path;
import retrofit2.http.POST;
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 ComputerVision.
 */
public class ComputerVisionImpl implements ComputerVision {
    /** The Retrofit service to perform REST calls. */
    private ComputerVisionService service;
    /** The service client containing this operation class. */
    private ComputerVisionClientImpl client;

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

    /**
     * The interface defining all the services for ComputerVision to be
     * used by Retrofit to perform actually REST calls.
     */
    interface ComputerVisionService {
        @Headers({ "Content-Type: application/octet-stream", "x-ms-logging-context: com.microsoft.azure.cognitiveservices.vision.computervision.ComputerVision readInStream" })
        @POST("read/analyze")
        Observable<Response<ResponseBody>> readInStream(@Query("language") OcrDetectionLanguage language, @Body RequestBody image, @Query("pages") String pages, @Query("model-version") String modelVersion, @Query("readingOrder") String readingOrder, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/octet-stream", "x-ms-logging-context: com.microsoft.azure.cognitiveservices.vision.computervision.ComputerVision tagImageInStream" })
        @POST("tag")
        Observable<Response<ResponseBody>> tagImageInStream(@Query("language") String language, @Body RequestBody image, @Query("model-version") String modelVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/octet-stream", "x-ms-logging-context: com.microsoft.azure.cognitiveservices.vision.computervision.ComputerVision recognizePrintedTextInStream" })
        @POST("ocr")
        Observable<Response<ResponseBody>> recognizePrintedTextInStream(@Query("detectOrientation") boolean detectOrientation, @Query("language") OcrLanguages language, @Body RequestBody image, @Query("model-version") String modelVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/octet-stream", "x-ms-logging-context: com.microsoft.azure.cognitiveservices.vision.computervision.ComputerVision analyzeImageByDomainInStream" })
        @POST("models/{model}/analyze")
        Observable<Response<ResponseBody>> analyzeImageByDomainInStream(@Path("model") String model, @Query("language") String language, @Body RequestBody image, @Query("model-version") String modelVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/octet-stream", "x-ms-logging-context: com.microsoft.azure.cognitiveservices.vision.computervision.ComputerVision generateThumbnailInStream" })
        @POST("generateThumbnail")
        @Streaming
        Observable<Response<ResponseBody>> generateThumbnailInStream(@Query("width") int width, @Query("height") int height, @Query("smartCropping") Boolean smartCropping, @Body RequestBody image, @Query("model-version") String modelVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/octet-stream", "x-ms-logging-context: com.microsoft.azure.cognitiveservices.vision.computervision.ComputerVision detectObjectsInStream" })
        @POST("detect")
        Observable<Response<ResponseBody>> detectObjectsInStream(@Body RequestBody image, @Query("model-version") String modelVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/octet-stream", "x-ms-logging-context: com.microsoft.azure.cognitiveservices.vision.computervision.ComputerVision describeImageInStream" })
        @POST("describe")
        Observable<Response<ResponseBody>> describeImageInStream(@Query("maxCandidates") Integer maxCandidates, @Query("language") String language, @Query("descriptionExclude") String descriptionExclude1, @Body RequestBody image, @Query("model-version") String modelVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/octet-stream", "x-ms-logging-context: com.microsoft.azure.cognitiveservices.vision.computervision.ComputerVision getAreaOfInterestInStream" })
        @POST("areaOfInterest")
        Observable<Response<ResponseBody>> getAreaOfInterestInStream(@Body RequestBody image, @Query("model-version") String modelVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/octet-stream", "x-ms-logging-context: com.microsoft.azure.cognitiveservices.vision.computervision.ComputerVision analyzeImageInStream" })
        @POST("analyze")
        Observable<Response<ResponseBody>> analyzeImageInStream(@Query("visualFeatures") String visualFeatures, @Query("details") String details, @Query("language") String language, @Query("descriptionExclude") String descriptionExclude1, @Body RequestBody image, @Query("model-version") String modelVersion, @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.vision.computervision.ComputerVision getReadResult" })
        @GET("read/analyzeResults/{operationId}")
        Observable<Response<ResponseBody>> getReadResult(@Path("operationId") UUID operationId, @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.vision.computervision.ComputerVision read" })
        @POST("read/analyze")
        Observable<Response<ResponseBody>> read(@Query("language") OcrDetectionLanguage language, @Query("pages") String pages, @Query("model-version") String modelVersion, @Query("readingOrder") String readingOrder, @Header("accept-language") String acceptLanguage, @Body ImageUrl imageUrl, @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.vision.computervision.ComputerVision getAreaOfInterest" })
        @POST("areaOfInterest")
        Observable<Response<ResponseBody>> getAreaOfInterest(@Query("model-version") String modelVersion, @Header("accept-language") String acceptLanguage, @Body ImageUrl imageUrl, @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.vision.computervision.ComputerVision generateThumbnail" })
        @POST("generateThumbnail")
        @Streaming
        Observable<Response<ResponseBody>> generateThumbnail(@Query("width") int width, @Query("height") int height, @Query("smartCropping") Boolean smartCropping, @Query("model-version") String modelVersion, @Header("accept-language") String acceptLanguage, @Body ImageUrl imageUrl, @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.vision.computervision.ComputerVision tagImage" })
        @POST("tag")
        Observable<Response<ResponseBody>> tagImage(@Query("language") String language, @Query("model-version") String modelVersion, @Header("accept-language") String acceptLanguage, @Body ImageUrl imageUrl, @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.vision.computervision.ComputerVision recognizePrintedText" })
        @POST("ocr")
        Observable<Response<ResponseBody>> recognizePrintedText(@Query("detectOrientation") boolean detectOrientation, @Query("language") OcrLanguages language, @Query("model-version") String modelVersion, @Header("accept-language") String acceptLanguage, @Body ImageUrl imageUrl, @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.vision.computervision.ComputerVision analyzeImageByDomain" })
        @POST("models/{model}/analyze")
        Observable<Response<ResponseBody>> analyzeImageByDomain(@Path("model") String model, @Query("language") String language, @Query("model-version") String modelVersion, @Header("accept-language") String acceptLanguage, @Body ImageUrl imageUrl, @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.vision.computervision.ComputerVision listModels" })
        @GET("models")
        Observable<Response<ResponseBody>> listModels(@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.vision.computervision.ComputerVision detectObjects" })
        @POST("detect")
        Observable<Response<ResponseBody>> detectObjects(@Query("model-version") String modelVersion, @Header("accept-language") String acceptLanguage, @Body ImageUrl imageUrl, @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.vision.computervision.ComputerVision describeImage" })
        @POST("describe")
        Observable<Response<ResponseBody>> describeImage(@Query("maxCandidates") Integer maxCandidates, @Query("language") String language, @Query("descriptionExclude") String descriptionExclude1, @Query("model-version") String modelVersion, @Header("accept-language") String acceptLanguage, @Body ImageUrl imageUrl, @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.vision.computervision.ComputerVision analyzeImage" })
        @POST("analyze")
        Observable<Response<ResponseBody>> analyzeImage(@Query("visualFeatures") String visualFeatures, @Query("details") String details, @Query("language") String language, @Query("descriptionExclude") String descriptionExclude1, @Query("model-version") String modelVersion, @Header("accept-language") String acceptLanguage, @Body ImageUrl imageUrl, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

    }


    /**
     * Use this interface to get the result of a Read operation, employing the state-of-the-art Optical Character Recognition (OCR) algorithms optimized for text-heavy documents. When you use the Read interface, the response contains a field called 'Operation-Location'. The 'Operation-Location' field contains the URL that you must use for your 'GetReadResult' operation to access OCR results.​.
     *
     * @param image An image stream.
     * @param readInStreamOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ComputerVisionOcrErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     */
    public void readInStream(byte[] image, ReadInStreamOptionalParameter readInStreamOptionalParameter) {
        readInStreamWithServiceResponseAsync(image, readInStreamOptionalParameter).toBlocking().single().body();
    }

    /**
     * Use this interface to get the result of a Read operation, employing the state-of-the-art Optical Character Recognition (OCR) algorithms optimized for text-heavy documents. When you use the Read interface, the response contains a field called 'Operation-Location'. The 'Operation-Location' field contains the URL that you must use for your 'GetReadResult' operation to access OCR results.​.
     *
     * @param image An image stream.
     * @param readInStreamOptionalParameter 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<Void> readInStreamAsync(byte[] image, ReadInStreamOptionalParameter readInStreamOptionalParameter, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(readInStreamWithServiceResponseAsync(image, readInStreamOptionalParameter), serviceCallback);
    }

    /**
     * Use this interface to get the result of a Read operation, employing the state-of-the-art Optical Character Recognition (OCR) algorithms optimized for text-heavy documents. When you use the Read interface, the response contains a field called 'Operation-Location'. The 'Operation-Location' field contains the URL that you must use for your 'GetReadResult' operation to access OCR results.​.
     *
     * @param image An image stream.
     * @param readInStreamOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> readInStreamAsync(byte[] image, ReadInStreamOptionalParameter readInStreamOptionalParameter) {
        return readInStreamWithServiceResponseAsync(image, readInStreamOptionalParameter).map(new Func1<ServiceResponseWithHeaders<Void, ReadInStreamHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, ReadInStreamHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Use this interface to get the result of a Read operation, employing the state-of-the-art Optical Character Recognition (OCR) algorithms optimized for text-heavy documents. When you use the Read interface, the response contains a field called 'Operation-Location'. The 'Operation-Location' field contains the URL that you must use for your 'GetReadResult' operation to access OCR results.​.
     *
     * @param image An image stream.
     * @param readInStreamOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, ReadInStreamHeaders>> readInStreamWithServiceResponseAsync(byte[] image, ReadInStreamOptionalParameter readInStreamOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (image == null) {
            throw new IllegalArgumentException("Parameter image is required and cannot be null.");
        }
        final OcrDetectionLanguage language = readInStreamOptionalParameter != null ? readInStreamOptionalParameter.language() : null;
        final List<String> pages = readInStreamOptionalParameter != null ? readInStreamOptionalParameter.pages() : null;
        final String modelVersion = readInStreamOptionalParameter != null ? readInStreamOptionalParameter.modelVersion() : null;
        final String readingOrder = readInStreamOptionalParameter != null ? readInStreamOptionalParameter.readingOrder() : null;

        return readInStreamWithServiceResponseAsync(image, language, pages, modelVersion, readingOrder);
    }

    /**
     * Use this interface to get the result of a Read operation, employing the state-of-the-art Optical Character Recognition (OCR) algorithms optimized for text-heavy documents. When you use the Read interface, the response contains a field called 'Operation-Location'. The 'Operation-Location' field contains the URL that you must use for your 'GetReadResult' operation to access OCR results.​.
     *
     * @param image An image stream.
     * @param language The BCP-47 language code of the text in the document. Read supports auto language identification and multi-language documents, so only provide a language code if you would like to force the document to be processed in that specific language. See https://aka.ms/ocr-languages for list of supported languages. Possible values include: 'af', 'ast', 'bi', 'br', 'ca', 'ceb', 'ch', 'co', 'crh', 'cs', 'csb', 'da', 'de', 'en', 'es', 'et', 'eu', 'fi', 'fil', 'fj', 'fr', 'fur', 'fy', 'ga', 'gd', 'gil', 'gl', 'gv', 'hni', 'hsb', 'ht', 'hu', 'ia', 'id', 'it', 'iu', 'ja', 'jv', 'kaa', 'kac', 'kea', 'kha', 'kl', 'ko', 'ku', 'kw', 'lb', 'ms', 'mww', 'nap', 'nl', 'no', 'oc', 'pl', 'pt', 'quc', 'rm', 'sco', 'sl', 'sq', 'sv', 'sw', 'tet', 'tr', 'tt', 'uz', 'vo', 'wae', 'yua', 'za', 'zh-Hans', 'zh-Hant', 'zu'
     * @param pages Custom page numbers for multi-page documents(PDF/TIFF), input the number of the pages you want to get OCR result. For a range of pages, use a hyphen. Separate each page or range with a comma.
     * @param modelVersion Optional parameter to specify the version of the OCR model used for text extraction. Accepted values are: "latest", "latest-preview", "2021-04-12". Defaults to "latest".
     * @param readingOrder Optional parameter to specify which reading order algorithm should be applied when ordering the extract text elements. Can be either 'basic' or 'natural'. Will default to 'basic' if not specified
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, ReadInStreamHeaders>> readInStreamWithServiceResponseAsync(byte[] image, OcrDetectionLanguage language, List<String> pages, String modelVersion, String readingOrder) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (image == null) {
            throw new IllegalArgumentException("Parameter image is required and cannot be null.");
        }
        Validator.validate(pages);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        RequestBody imageConverted = RequestBody.create(MediaType.parse("application/octet-stream"), image);
        String pagesConverted = this.client.serializerAdapter().serializeList(pages, CollectionFormat.CSV);
        return service.readInStream(language, imageConverted, pagesConverted, modelVersion, readingOrder, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, ReadInStreamHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, ReadInStreamHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, ReadInStreamHeaders> clientResponse = readInStreamDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public ComputerVisionReadInStreamParameters readInStream() {
        return new ComputerVisionReadInStreamParameters(this);
    }

    /**
     * Internal class implementing ComputerVisionReadInStreamDefinition.
     */
    class ComputerVisionReadInStreamParameters implements ComputerVisionReadInStreamDefinition {
        private ComputerVisionImpl parent;
        private byte[] image;
        private OcrDetectionLanguage language;
        private List<String> pages;
        private String modelVersion;
        private String readingOrder;

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

        @Override
        public ComputerVisionReadInStreamParameters withImage(byte[] image) {
            this.image = image;
            return this;
        }

        @Override
        public ComputerVisionReadInStreamParameters withLanguage(OcrDetectionLanguage language) {
            this.language = language;
            return this;
        }

        @Override
        public ComputerVisionReadInStreamParameters withPages(List<String> pages) {
            this.pages = pages;
            return this;
        }

        @Override
        public ComputerVisionReadInStreamParameters withModelVersion(String modelVersion) {
            this.modelVersion = modelVersion;
            return this;
        }

        @Override
        public ComputerVisionReadInStreamParameters withReadingOrder(String readingOrder) {
            this.readingOrder = readingOrder;
            return this;
        }

        @Override
        public void execute() {
        readInStreamWithServiceResponseAsync(image, language, pages, modelVersion, readingOrder).toBlocking().single().body();
    }

        @Override
        public Observable<Void> executeAsync() {
            return readInStreamWithServiceResponseAsync(image, language, pages, modelVersion, readingOrder).map(new Func1<ServiceResponseWithHeaders<Void, ReadInStreamHeaders>, Void>() {
                @Override
                public Void call(ServiceResponseWithHeaders<Void, ReadInStreamHeaders> response) {
                    return response.body();
                }
            });
        }
    }


    /**
     * This operation generates a list of words, or tags, that are relevant to the content of the supplied image. The Computer Vision API can return tags based on objects, living beings, scenery or actions found in images. Unlike categories, tags are not organized according to a hierarchical classification system, but correspond to image content. Tags may contain hints to avoid ambiguity or provide context, for example the tag "ascomycete" may be accompanied by the hint "fungus".
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param image An image stream.
     * @param tagImageInStreamOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ComputerVisionErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the TagResult object if successful.
     */
    public TagResult tagImageInStream(byte[] image, TagImageInStreamOptionalParameter tagImageInStreamOptionalParameter) {
        return tagImageInStreamWithServiceResponseAsync(image, tagImageInStreamOptionalParameter).toBlocking().single().body();
    }

    /**
     * This operation generates a list of words, or tags, that are relevant to the content of the supplied image. The Computer Vision API can return tags based on objects, living beings, scenery or actions found in images. Unlike categories, tags are not organized according to a hierarchical classification system, but correspond to image content. Tags may contain hints to avoid ambiguity or provide context, for example the tag "ascomycete" may be accompanied by the hint "fungus".
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param image An image stream.
     * @param tagImageInStreamOptionalParameter 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<TagResult> tagImageInStreamAsync(byte[] image, TagImageInStreamOptionalParameter tagImageInStreamOptionalParameter, final ServiceCallback<TagResult> serviceCallback) {
        return ServiceFuture.fromResponse(tagImageInStreamWithServiceResponseAsync(image, tagImageInStreamOptionalParameter), serviceCallback);
    }

    /**
     * This operation generates a list of words, or tags, that are relevant to the content of the supplied image. The Computer Vision API can return tags based on objects, living beings, scenery or actions found in images. Unlike categories, tags are not organized according to a hierarchical classification system, but correspond to image content. Tags may contain hints to avoid ambiguity or provide context, for example the tag "ascomycete" may be accompanied by the hint "fungus".
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param image An image stream.
     * @param tagImageInStreamOptionalParameter 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 TagResult object
     */
    public Observable<TagResult> tagImageInStreamAsync(byte[] image, TagImageInStreamOptionalParameter tagImageInStreamOptionalParameter) {
        return tagImageInStreamWithServiceResponseAsync(image, tagImageInStreamOptionalParameter).map(new Func1<ServiceResponse<TagResult>, TagResult>() {
            @Override
            public TagResult call(ServiceResponse<TagResult> response) {
                return response.body();
            }
        });
    }

    /**
     * This operation generates a list of words, or tags, that are relevant to the content of the supplied image. The Computer Vision API can return tags based on objects, living beings, scenery or actions found in images. Unlike categories, tags are not organized according to a hierarchical classification system, but correspond to image content. Tags may contain hints to avoid ambiguity or provide context, for example the tag "ascomycete" may be accompanied by the hint "fungus".
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param image An image stream.
     * @param tagImageInStreamOptionalParameter 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 TagResult object
     */
    public Observable<ServiceResponse<TagResult>> tagImageInStreamWithServiceResponseAsync(byte[] image, TagImageInStreamOptionalParameter tagImageInStreamOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (image == null) {
            throw new IllegalArgumentException("Parameter image is required and cannot be null.");
        }
        final String language = tagImageInStreamOptionalParameter != null ? tagImageInStreamOptionalParameter.language() : null;
        final String modelVersion = tagImageInStreamOptionalParameter != null ? tagImageInStreamOptionalParameter.modelVersion() : null;

        return tagImageInStreamWithServiceResponseAsync(image, language, modelVersion);
    }

    /**
     * This operation generates a list of words, or tags, that are relevant to the content of the supplied image. The Computer Vision API can return tags based on objects, living beings, scenery or actions found in images. Unlike categories, tags are not organized according to a hierarchical classification system, but correspond to image content. Tags may contain hints to avoid ambiguity or provide context, for example the tag "ascomycete" may be accompanied by the hint "fungus".
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param image An image stream.
     * @param language The desired language for output generation. If this parameter is not specified, the default value is &amp;quot;en&amp;quot;.Supported languages:en - English, Default. es - Spanish, ja - Japanese, pt - Portuguese, zh - Simplified Chinese. Possible values include: 'en', 'es', 'ja', 'pt', 'zh'
     * @param modelVersion Optional parameter to specify the version of the AI model. Accepted values are: "latest", "2021-04-01". Defaults to "latest".
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the TagResult object
     */
    public Observable<ServiceResponse<TagResult>> tagImageInStreamWithServiceResponseAsync(byte[] image, String language, String modelVersion) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (image == null) {
            throw new IllegalArgumentException("Parameter image is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        RequestBody imageConverted = RequestBody.create(MediaType.parse("application/octet-stream"), image);
        return service.tagImageInStream(language, imageConverted, modelVersion, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<TagResult>>>() {
                @Override
                public Observable<ServiceResponse<TagResult>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<TagResult> clientResponse = tagImageInStreamDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public ComputerVisionTagImageInStreamParameters tagImageInStream() {
        return new ComputerVisionTagImageInStreamParameters(this);
    }

    /**
     * Internal class implementing ComputerVisionTagImageInStreamDefinition.
     */
    class ComputerVisionTagImageInStreamParameters implements ComputerVisionTagImageInStreamDefinition {
        private ComputerVisionImpl parent;
        private byte[] image;
        private String language;
        private String modelVersion;

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

        @Override
        public ComputerVisionTagImageInStreamParameters withImage(byte[] image) {
            this.image = image;
            return this;
        }

        @Override
        public ComputerVisionTagImageInStreamParameters withLanguage(String language) {
            this.language = language;
            return this;
        }

        @Override
        public ComputerVisionTagImageInStreamParameters withModelVersion(String modelVersion) {
            this.modelVersion = modelVersion;
            return this;
        }

        @Override
        public TagResult execute() {
        return tagImageInStreamWithServiceResponseAsync(image, language, modelVersion).toBlocking().single().body();
    }

        @Override
        public Observable<TagResult> executeAsync() {
            return tagImageInStreamWithServiceResponseAsync(image, language, modelVersion).map(new Func1<ServiceResponse<TagResult>, TagResult>() {
                @Override
                public TagResult call(ServiceResponse<TagResult> response) {
                    return response.body();
                }
            });
        }
    }


    /**
     * Optical Character Recognition (OCR) detects text in an image and extracts the recognized characters into a machine-usable character stream.
     Upon success, the OCR results will be returned.
     Upon failure, the error code together with an error message will be returned. The error code can be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage, NotSupportedLanguage, or InternalServerError.
     *
     * @param detectOrientation Whether detect the text orientation in the image. With detectOrientation=true the OCR service tries to detect the image orientation and correct it before further processing (e.g. if it's upside-down).
     * @param image An image stream.
     * @param recognizePrintedTextInStreamOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ComputerVisionErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the OcrResult object if successful.
     */
    public OcrResult recognizePrintedTextInStream(boolean detectOrientation, byte[] image, RecognizePrintedTextInStreamOptionalParameter recognizePrintedTextInStreamOptionalParameter) {
        return recognizePrintedTextInStreamWithServiceResponseAsync(detectOrientation, image, recognizePrintedTextInStreamOptionalParameter).toBlocking().single().body();
    }

    /**
     * Optical Character Recognition (OCR) detects text in an image and extracts the recognized characters into a machine-usable character stream.
     Upon success, the OCR results will be returned.
     Upon failure, the error code together with an error message will be returned. The error code can be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage, NotSupportedLanguage, or InternalServerError.
     *
     * @param detectOrientation Whether detect the text orientation in the image. With detectOrientation=true the OCR service tries to detect the image orientation and correct it before further processing (e.g. if it's upside-down).
     * @param image An image stream.
     * @param recognizePrintedTextInStreamOptionalParameter 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<OcrResult> recognizePrintedTextInStreamAsync(boolean detectOrientation, byte[] image, RecognizePrintedTextInStreamOptionalParameter recognizePrintedTextInStreamOptionalParameter, final ServiceCallback<OcrResult> serviceCallback) {
        return ServiceFuture.fromResponse(recognizePrintedTextInStreamWithServiceResponseAsync(detectOrientation, image, recognizePrintedTextInStreamOptionalParameter), serviceCallback);
    }

    /**
     * Optical Character Recognition (OCR) detects text in an image and extracts the recognized characters into a machine-usable character stream.
     Upon success, the OCR results will be returned.
     Upon failure, the error code together with an error message will be returned. The error code can be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage, NotSupportedLanguage, or InternalServerError.
     *
     * @param detectOrientation Whether detect the text orientation in the image. With detectOrientation=true the OCR service tries to detect the image orientation and correct it before further processing (e.g. if it's upside-down).
     * @param image An image stream.
     * @param recognizePrintedTextInStreamOptionalParameter 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 OcrResult object
     */
    public Observable<OcrResult> recognizePrintedTextInStreamAsync(boolean detectOrientation, byte[] image, RecognizePrintedTextInStreamOptionalParameter recognizePrintedTextInStreamOptionalParameter) {
        return recognizePrintedTextInStreamWithServiceResponseAsync(detectOrientation, image, recognizePrintedTextInStreamOptionalParameter).map(new Func1<ServiceResponse<OcrResult>, OcrResult>() {
            @Override
            public OcrResult call(ServiceResponse<OcrResult> response) {
                return response.body();
            }
        });
    }

    /**
     * Optical Character Recognition (OCR) detects text in an image and extracts the recognized characters into a machine-usable character stream.
     Upon success, the OCR results will be returned.
     Upon failure, the error code together with an error message will be returned. The error code can be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage, NotSupportedLanguage, or InternalServerError.
     *
     * @param detectOrientation Whether detect the text orientation in the image. With detectOrientation=true the OCR service tries to detect the image orientation and correct it before further processing (e.g. if it's upside-down).
     * @param image An image stream.
     * @param recognizePrintedTextInStreamOptionalParameter 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 OcrResult object
     */
    public Observable<ServiceResponse<OcrResult>> recognizePrintedTextInStreamWithServiceResponseAsync(boolean detectOrientation, byte[] image, RecognizePrintedTextInStreamOptionalParameter recognizePrintedTextInStreamOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (image == null) {
            throw new IllegalArgumentException("Parameter image is required and cannot be null.");
        }
        final OcrLanguages language = recognizePrintedTextInStreamOptionalParameter != null ? recognizePrintedTextInStreamOptionalParameter.language() : null;
        final String modelVersion = recognizePrintedTextInStreamOptionalParameter != null ? recognizePrintedTextInStreamOptionalParameter.modelVersion() : null;

        return recognizePrintedTextInStreamWithServiceResponseAsync(detectOrientation, image, language, modelVersion);
    }

    /**
     * Optical Character Recognition (OCR) detects text in an image and extracts the recognized characters into a machine-usable character stream.
     Upon success, the OCR results will be returned.
     Upon failure, the error code together with an error message will be returned. The error code can be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage, NotSupportedLanguage, or InternalServerError.
     *
     * @param detectOrientation Whether detect the text orientation in the image. With detectOrientation=true the OCR service tries to detect the image orientation and correct it before further processing (e.g. if it's upside-down).
     * @param image An image stream.
     * @param language The BCP-47 language code of the text to be detected in the image. The default value is 'unk'. Possible values include: 'unk', 'zh-Hans', 'zh-Hant', 'cs', 'da', 'nl', 'en', 'fi', 'fr', 'de', 'el', 'hu', 'it', 'ja', 'ko', 'nb', 'pl', 'pt', 'ru', 'es', 'sv', 'tr', 'ar', 'ro', 'sr-Cyrl', 'sr-Latn', 'sk'
     * @param modelVersion Optional parameter to specify the version of the AI model. Accepted values are: "latest", "2021-04-01". Defaults to "latest".
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the OcrResult object
     */
    public Observable<ServiceResponse<OcrResult>> recognizePrintedTextInStreamWithServiceResponseAsync(boolean detectOrientation, byte[] image, OcrLanguages language, String modelVersion) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (image == null) {
            throw new IllegalArgumentException("Parameter image is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        RequestBody imageConverted = RequestBody.create(MediaType.parse("application/octet-stream"), image);
        return service.recognizePrintedTextInStream(detectOrientation, language, imageConverted, modelVersion, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<OcrResult>>>() {
                @Override
                public Observable<ServiceResponse<OcrResult>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<OcrResult> clientResponse = recognizePrintedTextInStreamDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public ComputerVisionRecognizePrintedTextInStreamParameters recognizePrintedTextInStream() {
        return new ComputerVisionRecognizePrintedTextInStreamParameters(this);
    }

    /**
     * Internal class implementing ComputerVisionRecognizePrintedTextInStreamDefinition.
     */
    class ComputerVisionRecognizePrintedTextInStreamParameters implements ComputerVisionRecognizePrintedTextInStreamDefinition {
        private ComputerVisionImpl parent;
        private boolean detectOrientation;
        private byte[] image;
        private OcrLanguages language;
        private String modelVersion;

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

        @Override
        public ComputerVisionRecognizePrintedTextInStreamParameters withDetectOrientation(boolean detectOrientation) {
            this.detectOrientation = detectOrientation;
            return this;
        }

        @Override
        public ComputerVisionRecognizePrintedTextInStreamParameters withImage(byte[] image) {
            this.image = image;
            return this;
        }

        @Override
        public ComputerVisionRecognizePrintedTextInStreamParameters withLanguage(OcrLanguages language) {
            this.language = language;
            return this;
        }

        @Override
        public ComputerVisionRecognizePrintedTextInStreamParameters withModelVersion(String modelVersion) {
            this.modelVersion = modelVersion;
            return this;
        }

        @Override
        public OcrResult execute() {
        return recognizePrintedTextInStreamWithServiceResponseAsync(detectOrientation, image, language, modelVersion).toBlocking().single().body();
    }

        @Override
        public Observable<OcrResult> executeAsync() {
            return recognizePrintedTextInStreamWithServiceResponseAsync(detectOrientation, image, language, modelVersion).map(new Func1<ServiceResponse<OcrResult>, OcrResult>() {
                @Override
                public OcrResult call(ServiceResponse<OcrResult> response) {
                    return response.body();
                }
            });
        }
    }


    /**
     * This operation recognizes content within an image by applying a domain-specific model. The list of domain-specific models that are supported by the Computer Vision API can be retrieved using the /models GET request. Currently, the API provides following domain-specific models: celebrities, landmarks.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON.
     If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param model The domain-specific content to recognize.
     * @param image An image stream.
     * @param analyzeImageByDomainInStreamOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ComputerVisionErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the DomainModelResults object if successful.
     */
    public DomainModelResults analyzeImageByDomainInStream(String model, byte[] image, AnalyzeImageByDomainInStreamOptionalParameter analyzeImageByDomainInStreamOptionalParameter) {
        return analyzeImageByDomainInStreamWithServiceResponseAsync(model, image, analyzeImageByDomainInStreamOptionalParameter).toBlocking().single().body();
    }

    /**
     * This operation recognizes content within an image by applying a domain-specific model. The list of domain-specific models that are supported by the Computer Vision API can be retrieved using the /models GET request. Currently, the API provides following domain-specific models: celebrities, landmarks.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON.
     If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param model The domain-specific content to recognize.
     * @param image An image stream.
     * @param analyzeImageByDomainInStreamOptionalParameter 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<DomainModelResults> analyzeImageByDomainInStreamAsync(String model, byte[] image, AnalyzeImageByDomainInStreamOptionalParameter analyzeImageByDomainInStreamOptionalParameter, final ServiceCallback<DomainModelResults> serviceCallback) {
        return ServiceFuture.fromResponse(analyzeImageByDomainInStreamWithServiceResponseAsync(model, image, analyzeImageByDomainInStreamOptionalParameter), serviceCallback);
    }

    /**
     * This operation recognizes content within an image by applying a domain-specific model. The list of domain-specific models that are supported by the Computer Vision API can be retrieved using the /models GET request. Currently, the API provides following domain-specific models: celebrities, landmarks.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON.
     If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param model The domain-specific content to recognize.
     * @param image An image stream.
     * @param analyzeImageByDomainInStreamOptionalParameter 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 DomainModelResults object
     */
    public Observable<DomainModelResults> analyzeImageByDomainInStreamAsync(String model, byte[] image, AnalyzeImageByDomainInStreamOptionalParameter analyzeImageByDomainInStreamOptionalParameter) {
        return analyzeImageByDomainInStreamWithServiceResponseAsync(model, image, analyzeImageByDomainInStreamOptionalParameter).map(new Func1<ServiceResponse<DomainModelResults>, DomainModelResults>() {
            @Override
            public DomainModelResults call(ServiceResponse<DomainModelResults> response) {
                return response.body();
            }
        });
    }

    /**
     * This operation recognizes content within an image by applying a domain-specific model. The list of domain-specific models that are supported by the Computer Vision API can be retrieved using the /models GET request. Currently, the API provides following domain-specific models: celebrities, landmarks.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON.
     If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param model The domain-specific content to recognize.
     * @param image An image stream.
     * @param analyzeImageByDomainInStreamOptionalParameter 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 DomainModelResults object
     */
    public Observable<ServiceResponse<DomainModelResults>> analyzeImageByDomainInStreamWithServiceResponseAsync(String model, byte[] image, AnalyzeImageByDomainInStreamOptionalParameter analyzeImageByDomainInStreamOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (model == null) {
            throw new IllegalArgumentException("Parameter model is required and cannot be null.");
        }
        if (image == null) {
            throw new IllegalArgumentException("Parameter image is required and cannot be null.");
        }
        final String language = analyzeImageByDomainInStreamOptionalParameter != null ? analyzeImageByDomainInStreamOptionalParameter.language() : null;
        final String modelVersion = analyzeImageByDomainInStreamOptionalParameter != null ? analyzeImageByDomainInStreamOptionalParameter.modelVersion() : null;

        return analyzeImageByDomainInStreamWithServiceResponseAsync(model, image, language, modelVersion);
    }

    /**
     * This operation recognizes content within an image by applying a domain-specific model. The list of domain-specific models that are supported by the Computer Vision API can be retrieved using the /models GET request. Currently, the API provides following domain-specific models: celebrities, landmarks.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON.
     If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param model The domain-specific content to recognize.
     * @param image An image stream.
     * @param language The desired language for output generation. If this parameter is not specified, the default value is &amp;quot;en&amp;quot;.Supported languages:en - English, Default. es - Spanish, ja - Japanese, pt - Portuguese, zh - Simplified Chinese. Possible values include: 'en', 'es', 'ja', 'pt', 'zh'
     * @param modelVersion Optional parameter to specify the version of the AI model. Accepted values are: "latest", "2021-04-01". Defaults to "latest".
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DomainModelResults object
     */
    public Observable<ServiceResponse<DomainModelResults>> analyzeImageByDomainInStreamWithServiceResponseAsync(String model, byte[] image, String language, String modelVersion) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (model == null) {
            throw new IllegalArgumentException("Parameter model is required and cannot be null.");
        }
        if (image == null) {
            throw new IllegalArgumentException("Parameter image is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        RequestBody imageConverted = RequestBody.create(MediaType.parse("application/octet-stream"), image);
        return service.analyzeImageByDomainInStream(model, language, imageConverted, modelVersion, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<DomainModelResults>>>() {
                @Override
                public Observable<ServiceResponse<DomainModelResults>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<DomainModelResults> clientResponse = analyzeImageByDomainInStreamDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public ComputerVisionAnalyzeImageByDomainInStreamParameters analyzeImageByDomainInStream() {
        return new ComputerVisionAnalyzeImageByDomainInStreamParameters(this);
    }

    /**
     * Internal class implementing ComputerVisionAnalyzeImageByDomainInStreamDefinition.
     */
    class ComputerVisionAnalyzeImageByDomainInStreamParameters implements ComputerVisionAnalyzeImageByDomainInStreamDefinition {
        private ComputerVisionImpl parent;
        private String model;
        private byte[] image;
        private String language;
        private String modelVersion;

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

        @Override
        public ComputerVisionAnalyzeImageByDomainInStreamParameters withModel(String model) {
            this.model = model;
            return this;
        }

        @Override
        public ComputerVisionAnalyzeImageByDomainInStreamParameters withImage(byte[] image) {
            this.image = image;
            return this;
        }

        @Override
        public ComputerVisionAnalyzeImageByDomainInStreamParameters withLanguage(String language) {
            this.language = language;
            return this;
        }

        @Override
        public ComputerVisionAnalyzeImageByDomainInStreamParameters withModelVersion(String modelVersion) {
            this.modelVersion = modelVersion;
            return this;
        }

        @Override
        public DomainModelResults execute() {
        return analyzeImageByDomainInStreamWithServiceResponseAsync(model, image, language, modelVersion).toBlocking().single().body();
    }

        @Override
        public Observable<DomainModelResults> executeAsync() {
            return analyzeImageByDomainInStreamWithServiceResponseAsync(model, image, language, modelVersion).map(new Func1<ServiceResponse<DomainModelResults>, DomainModelResults>() {
                @Override
                public DomainModelResults call(ServiceResponse<DomainModelResults> response) {
                    return response.body();
                }
            });
        }
    }


    /**
     * This operation generates a thumbnail image with the user-specified width and height. By default, the service analyzes the image, identifies the region of interest (ROI), and generates smart cropping coordinates based on the ROI. Smart cropping helps when you specify an aspect ratio that differs from that of the input image.
     A successful response contains the thumbnail image binary. If the request failed, the response contains an error code and a message to help determine what went wrong.
     Upon failure, the error code and an error message are returned. The error code could be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, InvalidThumbnailSize, NotSupportedImage, FailedToProcess, Timeout, or InternalServerError.
     *
     * @param width Width of the thumbnail, in pixels. It must be between 1 and 1024. Recommended minimum of 50.
     * @param height Height of the thumbnail, in pixels. It must be between 1 and 1024. Recommended minimum of 50.
     * @param image An image stream.
     * @param generateThumbnailInStreamOptionalParameter the object representing the optional parameters to be set before calling this API
     * @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 generateThumbnailInStream(int width, int height, byte[] image, GenerateThumbnailInStreamOptionalParameter generateThumbnailInStreamOptionalParameter) {
        return generateThumbnailInStreamWithServiceResponseAsync(width, height, image, generateThumbnailInStreamOptionalParameter).toBlocking().single().body();
    }

    /**
     * This operation generates a thumbnail image with the user-specified width and height. By default, the service analyzes the image, identifies the region of interest (ROI), and generates smart cropping coordinates based on the ROI. Smart cropping helps when you specify an aspect ratio that differs from that of the input image.
     A successful response contains the thumbnail image binary. If the request failed, the response contains an error code and a message to help determine what went wrong.
     Upon failure, the error code and an error message are returned. The error code could be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, InvalidThumbnailSize, NotSupportedImage, FailedToProcess, Timeout, or InternalServerError.
     *
     * @param width Width of the thumbnail, in pixels. It must be between 1 and 1024. Recommended minimum of 50.
     * @param height Height of the thumbnail, in pixels. It must be between 1 and 1024. Recommended minimum of 50.
     * @param image An image stream.
     * @param generateThumbnailInStreamOptionalParameter 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<InputStream> generateThumbnailInStreamAsync(int width, int height, byte[] image, GenerateThumbnailInStreamOptionalParameter generateThumbnailInStreamOptionalParameter, final ServiceCallback<InputStream> serviceCallback) {
        return ServiceFuture.fromResponse(generateThumbnailInStreamWithServiceResponseAsync(width, height, image, generateThumbnailInStreamOptionalParameter), serviceCallback);
    }

    /**
     * This operation generates a thumbnail image with the user-specified width and height. By default, the service analyzes the image, identifies the region of interest (ROI), and generates smart cropping coordinates based on the ROI. Smart cropping helps when you specify an aspect ratio that differs from that of the input image.
     A successful response contains the thumbnail image binary. If the request failed, the response contains an error code and a message to help determine what went wrong.
     Upon failure, the error code and an error message are returned. The error code could be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, InvalidThumbnailSize, NotSupportedImage, FailedToProcess, Timeout, or InternalServerError.
     *
     * @param width Width of the thumbnail, in pixels. It must be between 1 and 1024. Recommended minimum of 50.
     * @param height Height of the thumbnail, in pixels. It must be between 1 and 1024. Recommended minimum of 50.
     * @param image An image stream.
     * @param generateThumbnailInStreamOptionalParameter 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 InputStream object
     */
    public Observable<InputStream> generateThumbnailInStreamAsync(int width, int height, byte[] image, GenerateThumbnailInStreamOptionalParameter generateThumbnailInStreamOptionalParameter) {
        return generateThumbnailInStreamWithServiceResponseAsync(width, height, image, generateThumbnailInStreamOptionalParameter).map(new Func1<ServiceResponse<InputStream>, InputStream>() {
            @Override
            public InputStream call(ServiceResponse<InputStream> response) {
                return response.body();
            }
        });
    }

    /**
     * This operation generates a thumbnail image with the user-specified width and height. By default, the service analyzes the image, identifies the region of interest (ROI), and generates smart cropping coordinates based on the ROI. Smart cropping helps when you specify an aspect ratio that differs from that of the input image.
     A successful response contains the thumbnail image binary. If the request failed, the response contains an error code and a message to help determine what went wrong.
     Upon failure, the error code and an error message are returned. The error code could be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, InvalidThumbnailSize, NotSupportedImage, FailedToProcess, Timeout, or InternalServerError.
     *
     * @param width Width of the thumbnail, in pixels. It must be between 1 and 1024. Recommended minimum of 50.
     * @param height Height of the thumbnail, in pixels. It must be between 1 and 1024. Recommended minimum of 50.
     * @param image An image stream.
     * @param generateThumbnailInStreamOptionalParameter 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 InputStream object
     */
    public Observable<ServiceResponse<InputStream>> generateThumbnailInStreamWithServiceResponseAsync(int width, int height, byte[] image, GenerateThumbnailInStreamOptionalParameter generateThumbnailInStreamOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (image == null) {
            throw new IllegalArgumentException("Parameter image is required and cannot be null.");
        }
        final Boolean smartCropping = generateThumbnailInStreamOptionalParameter != null ? generateThumbnailInStreamOptionalParameter.smartCropping() : null;
        final String modelVersion = generateThumbnailInStreamOptionalParameter != null ? generateThumbnailInStreamOptionalParameter.modelVersion() : null;

        return generateThumbnailInStreamWithServiceResponseAsync(width, height, image, smartCropping, modelVersion);
    }

    /**
     * This operation generates a thumbnail image with the user-specified width and height. By default, the service analyzes the image, identifies the region of interest (ROI), and generates smart cropping coordinates based on the ROI. Smart cropping helps when you specify an aspect ratio that differs from that of the input image.
     A successful response contains the thumbnail image binary. If the request failed, the response contains an error code and a message to help determine what went wrong.
     Upon failure, the error code and an error message are returned. The error code could be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, InvalidThumbnailSize, NotSupportedImage, FailedToProcess, Timeout, or InternalServerError.
     *
     * @param width Width of the thumbnail, in pixels. It must be between 1 and 1024. Recommended minimum of 50.
     * @param height Height of the thumbnail, in pixels. It must be between 1 and 1024. Recommended minimum of 50.
     * @param image An image stream.
     * @param smartCropping Boolean flag for enabling smart cropping.
     * @param modelVersion Optional parameter to specify the version of the AI model. Accepted values are: "latest", "2021-04-01". Defaults to "latest".
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the InputStream object
     */
    public Observable<ServiceResponse<InputStream>> generateThumbnailInStreamWithServiceResponseAsync(int width, int height, byte[] image, Boolean smartCropping, String modelVersion) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (image == null) {
            throw new IllegalArgumentException("Parameter image is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        RequestBody imageConverted = RequestBody.create(MediaType.parse("application/octet-stream"), image);
        return service.generateThumbnailInStream(width, height, smartCropping, imageConverted, modelVersion, 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 = generateThumbnailInStreamDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<InputStream> generateThumbnailInStreamDelegate(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);
    }

    @Override
    public ComputerVisionGenerateThumbnailInStreamParameters generateThumbnailInStream() {
        return new ComputerVisionGenerateThumbnailInStreamParameters(this);
    }

    /**
     * Internal class implementing ComputerVisionGenerateThumbnailInStreamDefinition.
     */
    class ComputerVisionGenerateThumbnailInStreamParameters implements ComputerVisionGenerateThumbnailInStreamDefinition {
        private ComputerVisionImpl parent;
        private int width;
        private int height;
        private byte[] image;
        private Boolean smartCropping;
        private String modelVersion;

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

        @Override
        public ComputerVisionGenerateThumbnailInStreamParameters withWidth(int width) {
            this.width = width;
            return this;
        }

        @Override
        public ComputerVisionGenerateThumbnailInStreamParameters withHeight(int height) {
            this.height = height;
            return this;
        }

        @Override
        public ComputerVisionGenerateThumbnailInStreamParameters withImage(byte[] image) {
            this.image = image;
            return this;
        }

        @Override
        public ComputerVisionGenerateThumbnailInStreamParameters withSmartCropping(Boolean smartCropping) {
            this.smartCropping = smartCropping;
            return this;
        }

        @Override
        public ComputerVisionGenerateThumbnailInStreamParameters withModelVersion(String modelVersion) {
            this.modelVersion = modelVersion;
            return this;
        }

        @Override
        public InputStream execute() {
        return generateThumbnailInStreamWithServiceResponseAsync(width, height, image, smartCropping, modelVersion).toBlocking().single().body();
    }

        @Override
        public Observable<InputStream> executeAsync() {
            return generateThumbnailInStreamWithServiceResponseAsync(width, height, image, smartCropping, modelVersion).map(new Func1<ServiceResponse<InputStream>, InputStream>() {
                @Override
                public InputStream call(ServiceResponse<InputStream> response) {
                    return response.body();
                }
            });
        }
    }


    /**
     * Performs object detection on the specified image.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param image An image stream.
     * @param detectObjectsInStreamOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ComputerVisionErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the DetectResult object if successful.
     */
    public DetectResult detectObjectsInStream(byte[] image, DetectObjectsInStreamOptionalParameter detectObjectsInStreamOptionalParameter) {
        return detectObjectsInStreamWithServiceResponseAsync(image, detectObjectsInStreamOptionalParameter).toBlocking().single().body();
    }

    /**
     * Performs object detection on the specified image.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param image An image stream.
     * @param detectObjectsInStreamOptionalParameter 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<DetectResult> detectObjectsInStreamAsync(byte[] image, DetectObjectsInStreamOptionalParameter detectObjectsInStreamOptionalParameter, final ServiceCallback<DetectResult> serviceCallback) {
        return ServiceFuture.fromResponse(detectObjectsInStreamWithServiceResponseAsync(image, detectObjectsInStreamOptionalParameter), serviceCallback);
    }

    /**
     * Performs object detection on the specified image.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param image An image stream.
     * @param detectObjectsInStreamOptionalParameter 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 DetectResult object
     */
    public Observable<DetectResult> detectObjectsInStreamAsync(byte[] image, DetectObjectsInStreamOptionalParameter detectObjectsInStreamOptionalParameter) {
        return detectObjectsInStreamWithServiceResponseAsync(image, detectObjectsInStreamOptionalParameter).map(new Func1<ServiceResponse<DetectResult>, DetectResult>() {
            @Override
            public DetectResult call(ServiceResponse<DetectResult> response) {
                return response.body();
            }
        });
    }

    /**
     * Performs object detection on the specified image.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param image An image stream.
     * @param detectObjectsInStreamOptionalParameter 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 DetectResult object
     */
    public Observable<ServiceResponse<DetectResult>> detectObjectsInStreamWithServiceResponseAsync(byte[] image, DetectObjectsInStreamOptionalParameter detectObjectsInStreamOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (image == null) {
            throw new IllegalArgumentException("Parameter image is required and cannot be null.");
        }
        final String modelVersion = detectObjectsInStreamOptionalParameter != null ? detectObjectsInStreamOptionalParameter.modelVersion() : null;

        return detectObjectsInStreamWithServiceResponseAsync(image, modelVersion);
    }

    /**
     * Performs object detection on the specified image.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param image An image stream.
     * @param modelVersion Optional parameter to specify the version of the AI model. Accepted values are: "latest", "2021-04-01". Defaults to "latest".
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DetectResult object
     */
    public Observable<ServiceResponse<DetectResult>> detectObjectsInStreamWithServiceResponseAsync(byte[] image, String modelVersion) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (image == null) {
            throw new IllegalArgumentException("Parameter image is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        RequestBody imageConverted = RequestBody.create(MediaType.parse("application/octet-stream"), image);
        return service.detectObjectsInStream(imageConverted, modelVersion, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<DetectResult>>>() {
                @Override
                public Observable<ServiceResponse<DetectResult>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<DetectResult> clientResponse = detectObjectsInStreamDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public ComputerVisionDetectObjectsInStreamParameters detectObjectsInStream() {
        return new ComputerVisionDetectObjectsInStreamParameters(this);
    }

    /**
     * Internal class implementing ComputerVisionDetectObjectsInStreamDefinition.
     */
    class ComputerVisionDetectObjectsInStreamParameters implements ComputerVisionDetectObjectsInStreamDefinition {
        private ComputerVisionImpl parent;
        private byte[] image;
        private String modelVersion;

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

        @Override
        public ComputerVisionDetectObjectsInStreamParameters withImage(byte[] image) {
            this.image = image;
            return this;
        }

        @Override
        public ComputerVisionDetectObjectsInStreamParameters withModelVersion(String modelVersion) {
            this.modelVersion = modelVersion;
            return this;
        }

        @Override
        public DetectResult execute() {
        return detectObjectsInStreamWithServiceResponseAsync(image, modelVersion).toBlocking().single().body();
    }

        @Override
        public Observable<DetectResult> executeAsync() {
            return detectObjectsInStreamWithServiceResponseAsync(image, modelVersion).map(new Func1<ServiceResponse<DetectResult>, DetectResult>() {
                @Override
                public DetectResult call(ServiceResponse<DetectResult> response) {
                    return response.body();
                }
            });
        }
    }


    /**
     * This operation generates a description of an image in human readable language with complete sentences. The description is based on a collection of content tags, which are also returned by the operation. More than one description can be generated for each image. Descriptions are ordered by their confidence score. Descriptions may include results from celebrity and landmark domain models, if applicable.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param image An image stream.
     * @param describeImageInStreamOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ComputerVisionErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the ImageDescription object if successful.
     */
    public ImageDescription describeImageInStream(byte[] image, DescribeImageInStreamOptionalParameter describeImageInStreamOptionalParameter) {
        return describeImageInStreamWithServiceResponseAsync(image, describeImageInStreamOptionalParameter).toBlocking().single().body();
    }

    /**
     * This operation generates a description of an image in human readable language with complete sentences. The description is based on a collection of content tags, which are also returned by the operation. More than one description can be generated for each image. Descriptions are ordered by their confidence score. Descriptions may include results from celebrity and landmark domain models, if applicable.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param image An image stream.
     * @param describeImageInStreamOptionalParameter 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<ImageDescription> describeImageInStreamAsync(byte[] image, DescribeImageInStreamOptionalParameter describeImageInStreamOptionalParameter, final ServiceCallback<ImageDescription> serviceCallback) {
        return ServiceFuture.fromResponse(describeImageInStreamWithServiceResponseAsync(image, describeImageInStreamOptionalParameter), serviceCallback);
    }

    /**
     * This operation generates a description of an image in human readable language with complete sentences. The description is based on a collection of content tags, which are also returned by the operation. More than one description can be generated for each image. Descriptions are ordered by their confidence score. Descriptions may include results from celebrity and landmark domain models, if applicable.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param image An image stream.
     * @param describeImageInStreamOptionalParameter 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 ImageDescription object
     */
    public Observable<ImageDescription> describeImageInStreamAsync(byte[] image, DescribeImageInStreamOptionalParameter describeImageInStreamOptionalParameter) {
        return describeImageInStreamWithServiceResponseAsync(image, describeImageInStreamOptionalParameter).map(new Func1<ServiceResponse<ImageDescription>, ImageDescription>() {
            @Override
            public ImageDescription call(ServiceResponse<ImageDescription> response) {
                return response.body();
            }
        });
    }

    /**
     * This operation generates a description of an image in human readable language with complete sentences. The description is based on a collection of content tags, which are also returned by the operation. More than one description can be generated for each image. Descriptions are ordered by their confidence score. Descriptions may include results from celebrity and landmark domain models, if applicable.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param image An image stream.
     * @param describeImageInStreamOptionalParameter 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 ImageDescription object
     */
    public Observable<ServiceResponse<ImageDescription>> describeImageInStreamWithServiceResponseAsync(byte[] image, DescribeImageInStreamOptionalParameter describeImageInStreamOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (image == null) {
            throw new IllegalArgumentException("Parameter image is required and cannot be null.");
        }
        final Integer maxCandidates = describeImageInStreamOptionalParameter != null ? describeImageInStreamOptionalParameter.maxCandidates() : null;
        final String language = describeImageInStreamOptionalParameter != null ? describeImageInStreamOptionalParameter.language() : null;
        final List<DescriptionExclude> descriptionExclude = describeImageInStreamOptionalParameter != null ? describeImageInStreamOptionalParameter.descriptionExclude() : null;
        final String modelVersion = describeImageInStreamOptionalParameter != null ? describeImageInStreamOptionalParameter.modelVersion() : null;

        return describeImageInStreamWithServiceResponseAsync(image, maxCandidates, language, descriptionExclude, modelVersion);
    }

    /**
     * This operation generates a description of an image in human readable language with complete sentences. The description is based on a collection of content tags, which are also returned by the operation. More than one description can be generated for each image. Descriptions are ordered by their confidence score. Descriptions may include results from celebrity and landmark domain models, if applicable.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param image An image stream.
     * @param maxCandidates Maximum number of candidate descriptions to be returned.  The default is 1.
     * @param language The desired language for output generation. If this parameter is not specified, the default value is &amp;quot;en&amp;quot;.Supported languages:en - English, Default. es - Spanish, ja - Japanese, pt - Portuguese, zh - Simplified Chinese. Possible values include: 'en', 'es', 'ja', 'pt', 'zh'
     * @param descriptionExclude Turn off specified domain models when generating the description.
     * @param modelVersion Optional parameter to specify the version of the AI model. Accepted values are: "latest", "2021-04-01". Defaults to "latest".
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the ImageDescription object
     */
    public Observable<ServiceResponse<ImageDescription>> describeImageInStreamWithServiceResponseAsync(byte[] image, Integer maxCandidates, String language, List<DescriptionExclude> descriptionExclude, String modelVersion) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (image == null) {
            throw new IllegalArgumentException("Parameter image is required and cannot be null.");
        }
        Validator.validate(descriptionExclude);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        String descriptionExcludeConverted = this.client.serializerAdapter().serializeList(descriptionExclude, CollectionFormat.CSV);
        RequestBody imageConverted = RequestBody.create(MediaType.parse("application/octet-stream"), image);
        return service.describeImageInStream(maxCandidates, language, descriptionExcludeConverted, imageConverted, modelVersion, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<ImageDescription>>>() {
                @Override
                public Observable<ServiceResponse<ImageDescription>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<ImageDescription> clientResponse = describeImageInStreamDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public ComputerVisionDescribeImageInStreamParameters describeImageInStream() {
        return new ComputerVisionDescribeImageInStreamParameters(this);
    }

    /**
     * Internal class implementing ComputerVisionDescribeImageInStreamDefinition.
     */
    class ComputerVisionDescribeImageInStreamParameters implements ComputerVisionDescribeImageInStreamDefinition {
        private ComputerVisionImpl parent;
        private byte[] image;
        private Integer maxCandidates;
        private String language;
        private List<DescriptionExclude> descriptionExclude;
        private String modelVersion;

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

        @Override
        public ComputerVisionDescribeImageInStreamParameters withImage(byte[] image) {
            this.image = image;
            return this;
        }

        @Override
        public ComputerVisionDescribeImageInStreamParameters withMaxCandidates(Integer maxCandidates) {
            this.maxCandidates = maxCandidates;
            return this;
        }

        @Override
        public ComputerVisionDescribeImageInStreamParameters withLanguage(String language) {
            this.language = language;
            return this;
        }

        @Override
        public ComputerVisionDescribeImageInStreamParameters withDescriptionExclude(List<DescriptionExclude> descriptionExclude) {
            this.descriptionExclude = descriptionExclude;
            return this;
        }

        @Override
        public ComputerVisionDescribeImageInStreamParameters withModelVersion(String modelVersion) {
            this.modelVersion = modelVersion;
            return this;
        }

        @Override
        public ImageDescription execute() {
        return describeImageInStreamWithServiceResponseAsync(image, maxCandidates, language, descriptionExclude, modelVersion).toBlocking().single().body();
    }

        @Override
        public Observable<ImageDescription> executeAsync() {
            return describeImageInStreamWithServiceResponseAsync(image, maxCandidates, language, descriptionExclude, modelVersion).map(new Func1<ServiceResponse<ImageDescription>, ImageDescription>() {
                @Override
                public ImageDescription call(ServiceResponse<ImageDescription> response) {
                    return response.body();
                }
            });
        }
    }


    /**
     * This operation returns a bounding box around the most important area of the image.
     A successful response will be returned in JSON. If the request failed, the response contains an error code and a message to help determine what went wrong.
     Upon failure, the error code and an error message are returned. The error code could be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage, FailedToProcess, Timeout, or InternalServerError.
     *
     * @param image An image stream.
     * @param getAreaOfInterestInStreamOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ComputerVisionErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the AreaOfInterestResult object if successful.
     */
    public AreaOfInterestResult getAreaOfInterestInStream(byte[] image, GetAreaOfInterestInStreamOptionalParameter getAreaOfInterestInStreamOptionalParameter) {
        return getAreaOfInterestInStreamWithServiceResponseAsync(image, getAreaOfInterestInStreamOptionalParameter).toBlocking().single().body();
    }

    /**
     * This operation returns a bounding box around the most important area of the image.
     A successful response will be returned in JSON. If the request failed, the response contains an error code and a message to help determine what went wrong.
     Upon failure, the error code and an error message are returned. The error code could be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage, FailedToProcess, Timeout, or InternalServerError.
     *
     * @param image An image stream.
     * @param getAreaOfInterestInStreamOptionalParameter 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<AreaOfInterestResult> getAreaOfInterestInStreamAsync(byte[] image, GetAreaOfInterestInStreamOptionalParameter getAreaOfInterestInStreamOptionalParameter, final ServiceCallback<AreaOfInterestResult> serviceCallback) {
        return ServiceFuture.fromResponse(getAreaOfInterestInStreamWithServiceResponseAsync(image, getAreaOfInterestInStreamOptionalParameter), serviceCallback);
    }

    /**
     * This operation returns a bounding box around the most important area of the image.
     A successful response will be returned in JSON. If the request failed, the response contains an error code and a message to help determine what went wrong.
     Upon failure, the error code and an error message are returned. The error code could be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage, FailedToProcess, Timeout, or InternalServerError.
     *
     * @param image An image stream.
     * @param getAreaOfInterestInStreamOptionalParameter 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 AreaOfInterestResult object
     */
    public Observable<AreaOfInterestResult> getAreaOfInterestInStreamAsync(byte[] image, GetAreaOfInterestInStreamOptionalParameter getAreaOfInterestInStreamOptionalParameter) {
        return getAreaOfInterestInStreamWithServiceResponseAsync(image, getAreaOfInterestInStreamOptionalParameter).map(new Func1<ServiceResponse<AreaOfInterestResult>, AreaOfInterestResult>() {
            @Override
            public AreaOfInterestResult call(ServiceResponse<AreaOfInterestResult> response) {
                return response.body();
            }
        });
    }

    /**
     * This operation returns a bounding box around the most important area of the image.
     A successful response will be returned in JSON. If the request failed, the response contains an error code and a message to help determine what went wrong.
     Upon failure, the error code and an error message are returned. The error code could be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage, FailedToProcess, Timeout, or InternalServerError.
     *
     * @param image An image stream.
     * @param getAreaOfInterestInStreamOptionalParameter 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 AreaOfInterestResult object
     */
    public Observable<ServiceResponse<AreaOfInterestResult>> getAreaOfInterestInStreamWithServiceResponseAsync(byte[] image, GetAreaOfInterestInStreamOptionalParameter getAreaOfInterestInStreamOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (image == null) {
            throw new IllegalArgumentException("Parameter image is required and cannot be null.");
        }
        final String modelVersion = getAreaOfInterestInStreamOptionalParameter != null ? getAreaOfInterestInStreamOptionalParameter.modelVersion() : null;

        return getAreaOfInterestInStreamWithServiceResponseAsync(image, modelVersion);
    }

    /**
     * This operation returns a bounding box around the most important area of the image.
     A successful response will be returned in JSON. If the request failed, the response contains an error code and a message to help determine what went wrong.
     Upon failure, the error code and an error message are returned. The error code could be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage, FailedToProcess, Timeout, or InternalServerError.
     *
     * @param image An image stream.
     * @param modelVersion Optional parameter to specify the version of the AI model. Accepted values are: "latest", "2021-04-01". Defaults to "latest".
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the AreaOfInterestResult object
     */
    public Observable<ServiceResponse<AreaOfInterestResult>> getAreaOfInterestInStreamWithServiceResponseAsync(byte[] image, String modelVersion) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (image == null) {
            throw new IllegalArgumentException("Parameter image is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        RequestBody imageConverted = RequestBody.create(MediaType.parse("application/octet-stream"), image);
        return service.getAreaOfInterestInStream(imageConverted, modelVersion, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<AreaOfInterestResult>>>() {
                @Override
                public Observable<ServiceResponse<AreaOfInterestResult>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<AreaOfInterestResult> clientResponse = getAreaOfInterestInStreamDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public ComputerVisionGetAreaOfInterestInStreamParameters getAreaOfInterestInStream() {
        return new ComputerVisionGetAreaOfInterestInStreamParameters(this);
    }

    /**
     * Internal class implementing ComputerVisionGetAreaOfInterestInStreamDefinition.
     */
    class ComputerVisionGetAreaOfInterestInStreamParameters implements ComputerVisionGetAreaOfInterestInStreamDefinition {
        private ComputerVisionImpl parent;
        private byte[] image;
        private String modelVersion;

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

        @Override
        public ComputerVisionGetAreaOfInterestInStreamParameters withImage(byte[] image) {
            this.image = image;
            return this;
        }

        @Override
        public ComputerVisionGetAreaOfInterestInStreamParameters withModelVersion(String modelVersion) {
            this.modelVersion = modelVersion;
            return this;
        }

        @Override
        public AreaOfInterestResult execute() {
        return getAreaOfInterestInStreamWithServiceResponseAsync(image, modelVersion).toBlocking().single().body();
    }

        @Override
        public Observable<AreaOfInterestResult> executeAsync() {
            return getAreaOfInterestInStreamWithServiceResponseAsync(image, modelVersion).map(new Func1<ServiceResponse<AreaOfInterestResult>, AreaOfInterestResult>() {
                @Override
                public AreaOfInterestResult call(ServiceResponse<AreaOfInterestResult> response) {
                    return response.body();
                }
            });
        }
    }


    /**
     * This operation extracts a rich set of visual features based on the image content.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL. Within your request, there is an optional parameter to allow you to choose which features to return. By default, image categories are returned in the response.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param image An image stream.
     * @param analyzeImageInStreamOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ComputerVisionErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the ImageAnalysis object if successful.
     */
    public ImageAnalysis analyzeImageInStream(byte[] image, AnalyzeImageInStreamOptionalParameter analyzeImageInStreamOptionalParameter) {
        return analyzeImageInStreamWithServiceResponseAsync(image, analyzeImageInStreamOptionalParameter).toBlocking().single().body();
    }

    /**
     * This operation extracts a rich set of visual features based on the image content.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL. Within your request, there is an optional parameter to allow you to choose which features to return. By default, image categories are returned in the response.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param image An image stream.
     * @param analyzeImageInStreamOptionalParameter 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<ImageAnalysis> analyzeImageInStreamAsync(byte[] image, AnalyzeImageInStreamOptionalParameter analyzeImageInStreamOptionalParameter, final ServiceCallback<ImageAnalysis> serviceCallback) {
        return ServiceFuture.fromResponse(analyzeImageInStreamWithServiceResponseAsync(image, analyzeImageInStreamOptionalParameter), serviceCallback);
    }

    /**
     * This operation extracts a rich set of visual features based on the image content.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL. Within your request, there is an optional parameter to allow you to choose which features to return. By default, image categories are returned in the response.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param image An image stream.
     * @param analyzeImageInStreamOptionalParameter 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 ImageAnalysis object
     */
    public Observable<ImageAnalysis> analyzeImageInStreamAsync(byte[] image, AnalyzeImageInStreamOptionalParameter analyzeImageInStreamOptionalParameter) {
        return analyzeImageInStreamWithServiceResponseAsync(image, analyzeImageInStreamOptionalParameter).map(new Func1<ServiceResponse<ImageAnalysis>, ImageAnalysis>() {
            @Override
            public ImageAnalysis call(ServiceResponse<ImageAnalysis> response) {
                return response.body();
            }
        });
    }

    /**
     * This operation extracts a rich set of visual features based on the image content.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL. Within your request, there is an optional parameter to allow you to choose which features to return. By default, image categories are returned in the response.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param image An image stream.
     * @param analyzeImageInStreamOptionalParameter 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 ImageAnalysis object
     */
    public Observable<ServiceResponse<ImageAnalysis>> analyzeImageInStreamWithServiceResponseAsync(byte[] image, AnalyzeImageInStreamOptionalParameter analyzeImageInStreamOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (image == null) {
            throw new IllegalArgumentException("Parameter image is required and cannot be null.");
        }
        final List<VisualFeatureTypes> visualFeatures = analyzeImageInStreamOptionalParameter != null ? analyzeImageInStreamOptionalParameter.visualFeatures() : null;
        final List<Details> details = analyzeImageInStreamOptionalParameter != null ? analyzeImageInStreamOptionalParameter.details() : null;
        final String language = analyzeImageInStreamOptionalParameter != null ? analyzeImageInStreamOptionalParameter.language() : null;
        final List<DescriptionExclude> descriptionExclude = analyzeImageInStreamOptionalParameter != null ? analyzeImageInStreamOptionalParameter.descriptionExclude() : null;
        final String modelVersion = analyzeImageInStreamOptionalParameter != null ? analyzeImageInStreamOptionalParameter.modelVersion() : null;

        return analyzeImageInStreamWithServiceResponseAsync(image, visualFeatures, details, language, descriptionExclude, modelVersion);
    }

    /**
     * This operation extracts a rich set of visual features based on the image content.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL. Within your request, there is an optional parameter to allow you to choose which features to return. By default, image categories are returned in the response.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param image An image stream.
     * @param visualFeatures A string indicating what visual feature types to return. Multiple values should be comma-separated. Valid visual feature types include: Categories - categorizes image content according to a taxonomy defined in documentation. Tags - tags the image with a detailed list of words related to the image content. Description - describes the image content with a complete English sentence. Faces - detects if faces are present. If present, generate coordinates, gender and age. ImageType - detects if image is clipart or a line drawing. Color - determines the accent color, dominant color, and whether an image is black&amp;white. Adult - detects if the image is pornographic in nature (depicts nudity or a sex act), or is gory (depicts extreme violence or blood). Sexually suggestive content (aka racy content) is also detected. Objects - detects various objects within an image, including the approximate location. The Objects argument is only available in English. Brands - detects various brands within an image, including the approximate location. The Brands argument is only available in English.
     * @param details A string indicating which domain-specific details to return. Multiple values should be comma-separated. Valid visual feature types include: Celebrities - identifies celebrities if detected in the image, Landmarks - identifies notable landmarks in the image.
     * @param language The desired language for output generation. If this parameter is not specified, the default value is &amp;quot;en&amp;quot;.Supported languages:en - English, Default. es - Spanish, ja - Japanese, pt - Portuguese, zh - Simplified Chinese. Possible values include: 'en', 'es', 'ja', 'pt', 'zh'
     * @param descriptionExclude Turn off specified domain models when generating the description.
     * @param modelVersion Optional parameter to specify the version of the AI model. Accepted values are: "latest", "2021-04-01". Defaults to "latest".
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the ImageAnalysis object
     */
    public Observable<ServiceResponse<ImageAnalysis>> analyzeImageInStreamWithServiceResponseAsync(byte[] image, List<VisualFeatureTypes> visualFeatures, List<Details> details, String language, List<DescriptionExclude> descriptionExclude, String modelVersion) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (image == null) {
            throw new IllegalArgumentException("Parameter image is required and cannot be null.");
        }
        Validator.validate(visualFeatures);
        Validator.validate(details);
        Validator.validate(descriptionExclude);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        String visualFeaturesConverted = this.client.serializerAdapter().serializeList(visualFeatures, CollectionFormat.CSV);
        String detailsConverted = this.client.serializerAdapter().serializeList(details, CollectionFormat.CSV);
        String descriptionExcludeConverted = this.client.serializerAdapter().serializeList(descriptionExclude, CollectionFormat.CSV);
        RequestBody imageConverted = RequestBody.create(MediaType.parse("application/octet-stream"), image);
        return service.analyzeImageInStream(visualFeaturesConverted, detailsConverted, language, descriptionExcludeConverted, imageConverted, modelVersion, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<ImageAnalysis>>>() {
                @Override
                public Observable<ServiceResponse<ImageAnalysis>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<ImageAnalysis> clientResponse = analyzeImageInStreamDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public ComputerVisionAnalyzeImageInStreamParameters analyzeImageInStream() {
        return new ComputerVisionAnalyzeImageInStreamParameters(this);
    }

    /**
     * Internal class implementing ComputerVisionAnalyzeImageInStreamDefinition.
     */
    class ComputerVisionAnalyzeImageInStreamParameters implements ComputerVisionAnalyzeImageInStreamDefinition {
        private ComputerVisionImpl parent;
        private byte[] image;
        private List<VisualFeatureTypes> visualFeatures;
        private List<Details> details;
        private String language;
        private List<DescriptionExclude> descriptionExclude;
        private String modelVersion;

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

        @Override
        public ComputerVisionAnalyzeImageInStreamParameters withImage(byte[] image) {
            this.image = image;
            return this;
        }

        @Override
        public ComputerVisionAnalyzeImageInStreamParameters withVisualFeatures(List<VisualFeatureTypes> visualFeatures) {
            this.visualFeatures = visualFeatures;
            return this;
        }

        @Override
        public ComputerVisionAnalyzeImageInStreamParameters withDetails(List<Details> details) {
            this.details = details;
            return this;
        }

        @Override
        public ComputerVisionAnalyzeImageInStreamParameters withLanguage(String language) {
            this.language = language;
            return this;
        }

        @Override
        public ComputerVisionAnalyzeImageInStreamParameters withDescriptionExclude(List<DescriptionExclude> descriptionExclude) {
            this.descriptionExclude = descriptionExclude;
            return this;
        }

        @Override
        public ComputerVisionAnalyzeImageInStreamParameters withModelVersion(String modelVersion) {
            this.modelVersion = modelVersion;
            return this;
        }

        @Override
        public ImageAnalysis execute() {
        return analyzeImageInStreamWithServiceResponseAsync(image, visualFeatures, details, language, descriptionExclude, modelVersion).toBlocking().single().body();
    }

        @Override
        public Observable<ImageAnalysis> executeAsync() {
            return analyzeImageInStreamWithServiceResponseAsync(image, visualFeatures, details, language, descriptionExclude, modelVersion).map(new Func1<ServiceResponse<ImageAnalysis>, ImageAnalysis>() {
                @Override
                public ImageAnalysis call(ServiceResponse<ImageAnalysis> response) {
                    return response.body();
                }
            });
        }
    }

    /**
     * This interface is used for getting OCR results of Read operation. The URL to this interface should be retrieved from 'Operation-Location' field returned from Read interface.
     *
     * @param operationId Id of read operation returned in the response of the 'Read' interface.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ComputerVisionOcrErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the ReadOperationResult object if successful.
     */
    public ReadOperationResult getReadResult(UUID operationId) {
        return getReadResultWithServiceResponseAsync(operationId).toBlocking().single().body();
    }

    /**
     * This interface is used for getting OCR results of Read operation. The URL to this interface should be retrieved from 'Operation-Location' field returned from Read interface.
     *
     * @param operationId Id of read operation returned in the response of the 'Read' interface.
     * @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<ReadOperationResult> getReadResultAsync(UUID operationId, final ServiceCallback<ReadOperationResult> serviceCallback) {
        return ServiceFuture.fromResponse(getReadResultWithServiceResponseAsync(operationId), serviceCallback);
    }

    /**
     * This interface is used for getting OCR results of Read operation. The URL to this interface should be retrieved from 'Operation-Location' field returned from Read interface.
     *
     * @param operationId Id of read operation returned in the response of the 'Read' interface.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the ReadOperationResult object
     */
    public Observable<ReadOperationResult> getReadResultAsync(UUID operationId) {
        return getReadResultWithServiceResponseAsync(operationId).map(new Func1<ServiceResponse<ReadOperationResult>, ReadOperationResult>() {
            @Override
            public ReadOperationResult call(ServiceResponse<ReadOperationResult> response) {
                return response.body();
            }
        });
    }

    /**
     * This interface is used for getting OCR results of Read operation. The URL to this interface should be retrieved from 'Operation-Location' field returned from Read interface.
     *
     * @param operationId Id of read operation returned in the response of the 'Read' interface.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the ReadOperationResult object
     */
    public Observable<ServiceResponse<ReadOperationResult>> getReadResultWithServiceResponseAsync(UUID operationId) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (operationId == null) {
            throw new IllegalArgumentException("Parameter operationId is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.getReadResult(operationId, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<ReadOperationResult>>>() {
                @Override
                public Observable<ServiceResponse<ReadOperationResult>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<ReadOperationResult> clientResponse = getReadResultDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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


    /**
     * Use this interface to get the result of a Read operation, employing the state-of-the-art Optical Character Recognition (OCR) algorithms optimized for text-heavy documents. When you use the Read interface, the response contains a field called 'Operation-Location'. The 'Operation-Location' field contains the URL that you must use for your 'GetReadResult' operation to access OCR results.​.
     *
     * @param url Publicly reachable URL of an image.
     * @param readOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ComputerVisionOcrErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     */
    public void read(String url, ReadOptionalParameter readOptionalParameter) {
        readWithServiceResponseAsync(url, readOptionalParameter).toBlocking().single().body();
    }

    /**
     * Use this interface to get the result of a Read operation, employing the state-of-the-art Optical Character Recognition (OCR) algorithms optimized for text-heavy documents. When you use the Read interface, the response contains a field called 'Operation-Location'. The 'Operation-Location' field contains the URL that you must use for your 'GetReadResult' operation to access OCR results.​.
     *
     * @param url Publicly reachable URL of an image.
     * @param readOptionalParameter 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<Void> readAsync(String url, ReadOptionalParameter readOptionalParameter, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(readWithServiceResponseAsync(url, readOptionalParameter), serviceCallback);
    }

    /**
     * Use this interface to get the result of a Read operation, employing the state-of-the-art Optical Character Recognition (OCR) algorithms optimized for text-heavy documents. When you use the Read interface, the response contains a field called 'Operation-Location'. The 'Operation-Location' field contains the URL that you must use for your 'GetReadResult' operation to access OCR results.​.
     *
     * @param url Publicly reachable URL of an image.
     * @param readOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> readAsync(String url, ReadOptionalParameter readOptionalParameter) {
        return readWithServiceResponseAsync(url, readOptionalParameter).map(new Func1<ServiceResponseWithHeaders<Void, ReadHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, ReadHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Use this interface to get the result of a Read operation, employing the state-of-the-art Optical Character Recognition (OCR) algorithms optimized for text-heavy documents. When you use the Read interface, the response contains a field called 'Operation-Location'. The 'Operation-Location' field contains the URL that you must use for your 'GetReadResult' operation to access OCR results.​.
     *
     * @param url Publicly reachable URL of an image.
     * @param readOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, ReadHeaders>> readWithServiceResponseAsync(String url, ReadOptionalParameter readOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (url == null) {
            throw new IllegalArgumentException("Parameter url is required and cannot be null.");
        }
        final OcrDetectionLanguage language = readOptionalParameter != null ? readOptionalParameter.language() : null;
        final List<String> pages = readOptionalParameter != null ? readOptionalParameter.pages() : null;
        final String modelVersion = readOptionalParameter != null ? readOptionalParameter.modelVersion() : null;
        final String readingOrder = readOptionalParameter != null ? readOptionalParameter.readingOrder() : null;

        return readWithServiceResponseAsync(url, language, pages, modelVersion, readingOrder);
    }

    /**
     * Use this interface to get the result of a Read operation, employing the state-of-the-art Optical Character Recognition (OCR) algorithms optimized for text-heavy documents. When you use the Read interface, the response contains a field called 'Operation-Location'. The 'Operation-Location' field contains the URL that you must use for your 'GetReadResult' operation to access OCR results.​.
     *
     * @param url Publicly reachable URL of an image.
     * @param language The BCP-47 language code of the text in the document. Read supports auto language identification and multi-language documents, so only provide a language code if you would like to force the document to be processed in that specific language. See https://aka.ms/ocr-languages for list of supported languages. Possible values include: 'af', 'ast', 'bi', 'br', 'ca', 'ceb', 'ch', 'co', 'crh', 'cs', 'csb', 'da', 'de', 'en', 'es', 'et', 'eu', 'fi', 'fil', 'fj', 'fr', 'fur', 'fy', 'ga', 'gd', 'gil', 'gl', 'gv', 'hni', 'hsb', 'ht', 'hu', 'ia', 'id', 'it', 'iu', 'ja', 'jv', 'kaa', 'kac', 'kea', 'kha', 'kl', 'ko', 'ku', 'kw', 'lb', 'ms', 'mww', 'nap', 'nl', 'no', 'oc', 'pl', 'pt', 'quc', 'rm', 'sco', 'sl', 'sq', 'sv', 'sw', 'tet', 'tr', 'tt', 'uz', 'vo', 'wae', 'yua', 'za', 'zh-Hans', 'zh-Hant', 'zu'
     * @param pages Custom page numbers for multi-page documents(PDF/TIFF), input the number of the pages you want to get OCR result. For a range of pages, use a hyphen. Separate each page or range with a comma.
     * @param modelVersion Optional parameter to specify the version of the OCR model used for text extraction. Accepted values are: "latest", "latest-preview", "2021-04-12". Defaults to "latest".
     * @param readingOrder Optional parameter to specify which reading order algorithm should be applied when ordering the extract text elements. Can be either 'basic' or 'natural'. Will default to 'basic' if not specified
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, ReadHeaders>> readWithServiceResponseAsync(String url, OcrDetectionLanguage language, List<String> pages, String modelVersion, String readingOrder) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (url == null) {
            throw new IllegalArgumentException("Parameter url is required and cannot be null.");
        }
        Validator.validate(pages);
        ImageUrl imageUrl = new ImageUrl();
        imageUrl.withUrl(url);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        String pagesConverted = this.client.serializerAdapter().serializeList(pages, CollectionFormat.CSV);
        return service.read(language, pagesConverted, modelVersion, readingOrder, this.client.acceptLanguage(), imageUrl, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, ReadHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, ReadHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, ReadHeaders> clientResponse = readDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public ComputerVisionReadParameters read() {
        return new ComputerVisionReadParameters(this);
    }

    /**
     * Internal class implementing ComputerVisionReadDefinition.
     */
    class ComputerVisionReadParameters implements ComputerVisionReadDefinition {
        private ComputerVisionImpl parent;
        private String url;
        private OcrDetectionLanguage language;
        private List<String> pages;
        private String modelVersion;
        private String readingOrder;

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

        @Override
        public ComputerVisionReadParameters withUrl(String url) {
            this.url = url;
            return this;
        }

        @Override
        public ComputerVisionReadParameters withLanguage(OcrDetectionLanguage language) {
            this.language = language;
            return this;
        }

        @Override
        public ComputerVisionReadParameters withPages(List<String> pages) {
            this.pages = pages;
            return this;
        }

        @Override
        public ComputerVisionReadParameters withModelVersion(String modelVersion) {
            this.modelVersion = modelVersion;
            return this;
        }

        @Override
        public ComputerVisionReadParameters withReadingOrder(String readingOrder) {
            this.readingOrder = readingOrder;
            return this;
        }

        @Override
        public void execute() {
        readWithServiceResponseAsync(url, language, pages, modelVersion, readingOrder).toBlocking().single().body();
    }

        @Override
        public Observable<Void> executeAsync() {
            return readWithServiceResponseAsync(url, language, pages, modelVersion, readingOrder).map(new Func1<ServiceResponseWithHeaders<Void, ReadHeaders>, Void>() {
                @Override
                public Void call(ServiceResponseWithHeaders<Void, ReadHeaders> response) {
                    return response.body();
                }
            });
        }
    }


    /**
     * This operation returns a bounding box around the most important area of the image.
     A successful response will be returned in JSON. If the request failed, the response contains an error code and a message to help determine what went wrong.
     Upon failure, the error code and an error message are returned. The error code could be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage, FailedToProcess, Timeout, or InternalServerError.
     *
     * @param url Publicly reachable URL of an image.
     * @param getAreaOfInterestOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ComputerVisionErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the AreaOfInterestResult object if successful.
     */
    public AreaOfInterestResult getAreaOfInterest(String url, GetAreaOfInterestOptionalParameter getAreaOfInterestOptionalParameter) {
        return getAreaOfInterestWithServiceResponseAsync(url, getAreaOfInterestOptionalParameter).toBlocking().single().body();
    }

    /**
     * This operation returns a bounding box around the most important area of the image.
     A successful response will be returned in JSON. If the request failed, the response contains an error code and a message to help determine what went wrong.
     Upon failure, the error code and an error message are returned. The error code could be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage, FailedToProcess, Timeout, or InternalServerError.
     *
     * @param url Publicly reachable URL of an image.
     * @param getAreaOfInterestOptionalParameter 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<AreaOfInterestResult> getAreaOfInterestAsync(String url, GetAreaOfInterestOptionalParameter getAreaOfInterestOptionalParameter, final ServiceCallback<AreaOfInterestResult> serviceCallback) {
        return ServiceFuture.fromResponse(getAreaOfInterestWithServiceResponseAsync(url, getAreaOfInterestOptionalParameter), serviceCallback);
    }

    /**
     * This operation returns a bounding box around the most important area of the image.
     A successful response will be returned in JSON. If the request failed, the response contains an error code and a message to help determine what went wrong.
     Upon failure, the error code and an error message are returned. The error code could be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage, FailedToProcess, Timeout, or InternalServerError.
     *
     * @param url Publicly reachable URL of an image.
     * @param getAreaOfInterestOptionalParameter 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 AreaOfInterestResult object
     */
    public Observable<AreaOfInterestResult> getAreaOfInterestAsync(String url, GetAreaOfInterestOptionalParameter getAreaOfInterestOptionalParameter) {
        return getAreaOfInterestWithServiceResponseAsync(url, getAreaOfInterestOptionalParameter).map(new Func1<ServiceResponse<AreaOfInterestResult>, AreaOfInterestResult>() {
            @Override
            public AreaOfInterestResult call(ServiceResponse<AreaOfInterestResult> response) {
                return response.body();
            }
        });
    }

    /**
     * This operation returns a bounding box around the most important area of the image.
     A successful response will be returned in JSON. If the request failed, the response contains an error code and a message to help determine what went wrong.
     Upon failure, the error code and an error message are returned. The error code could be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage, FailedToProcess, Timeout, or InternalServerError.
     *
     * @param url Publicly reachable URL of an image.
     * @param getAreaOfInterestOptionalParameter 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 AreaOfInterestResult object
     */
    public Observable<ServiceResponse<AreaOfInterestResult>> getAreaOfInterestWithServiceResponseAsync(String url, GetAreaOfInterestOptionalParameter getAreaOfInterestOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (url == null) {
            throw new IllegalArgumentException("Parameter url is required and cannot be null.");
        }
        final String modelVersion = getAreaOfInterestOptionalParameter != null ? getAreaOfInterestOptionalParameter.modelVersion() : null;

        return getAreaOfInterestWithServiceResponseAsync(url, modelVersion);
    }

    /**
     * This operation returns a bounding box around the most important area of the image.
     A successful response will be returned in JSON. If the request failed, the response contains an error code and a message to help determine what went wrong.
     Upon failure, the error code and an error message are returned. The error code could be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage, FailedToProcess, Timeout, or InternalServerError.
     *
     * @param url Publicly reachable URL of an image.
     * @param modelVersion Optional parameter to specify the version of the AI model. Accepted values are: "latest", "2021-04-01". Defaults to "latest".
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the AreaOfInterestResult object
     */
    public Observable<ServiceResponse<AreaOfInterestResult>> getAreaOfInterestWithServiceResponseAsync(String url, String modelVersion) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (url == null) {
            throw new IllegalArgumentException("Parameter url is required and cannot be null.");
        }
        ImageUrl imageUrl = new ImageUrl();
        imageUrl.withUrl(url);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.getAreaOfInterest(modelVersion, this.client.acceptLanguage(), imageUrl, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<AreaOfInterestResult>>>() {
                @Override
                public Observable<ServiceResponse<AreaOfInterestResult>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<AreaOfInterestResult> clientResponse = getAreaOfInterestDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public ComputerVisionGetAreaOfInterestParameters getAreaOfInterest() {
        return new ComputerVisionGetAreaOfInterestParameters(this);
    }

    /**
     * Internal class implementing ComputerVisionGetAreaOfInterestDefinition.
     */
    class ComputerVisionGetAreaOfInterestParameters implements ComputerVisionGetAreaOfInterestDefinition {
        private ComputerVisionImpl parent;
        private String url;
        private String modelVersion;

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

        @Override
        public ComputerVisionGetAreaOfInterestParameters withUrl(String url) {
            this.url = url;
            return this;
        }

        @Override
        public ComputerVisionGetAreaOfInterestParameters withModelVersion(String modelVersion) {
            this.modelVersion = modelVersion;
            return this;
        }

        @Override
        public AreaOfInterestResult execute() {
        return getAreaOfInterestWithServiceResponseAsync(url, modelVersion).toBlocking().single().body();
    }

        @Override
        public Observable<AreaOfInterestResult> executeAsync() {
            return getAreaOfInterestWithServiceResponseAsync(url, modelVersion).map(new Func1<ServiceResponse<AreaOfInterestResult>, AreaOfInterestResult>() {
                @Override
                public AreaOfInterestResult call(ServiceResponse<AreaOfInterestResult> response) {
                    return response.body();
                }
            });
        }
    }


    /**
     * This operation generates a thumbnail image with the user-specified width and height. By default, the service analyzes the image, identifies the region of interest (ROI), and generates smart cropping coordinates based on the ROI. Smart cropping helps when you specify an aspect ratio that differs from that of the input image.
     A successful response contains the thumbnail image binary. If the request failed, the response contains an error code and a message to help determine what went wrong.
     Upon failure, the error code and an error message are returned. The error code could be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, InvalidThumbnailSize, NotSupportedImage, FailedToProcess, Timeout, or InternalServerError.
     *
     * @param width Width of the thumbnail, in pixels. It must be between 1 and 1024. Recommended minimum of 50.
     * @param height Height of the thumbnail, in pixels. It must be between 1 and 1024. Recommended minimum of 50.
     * @param url Publicly reachable URL of an image.
     * @param generateThumbnailOptionalParameter the object representing the optional parameters to be set before calling this API
     * @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 generateThumbnail(int width, int height, String url, GenerateThumbnailOptionalParameter generateThumbnailOptionalParameter) {
        return generateThumbnailWithServiceResponseAsync(width, height, url, generateThumbnailOptionalParameter).toBlocking().single().body();
    }

    /**
     * This operation generates a thumbnail image with the user-specified width and height. By default, the service analyzes the image, identifies the region of interest (ROI), and generates smart cropping coordinates based on the ROI. Smart cropping helps when you specify an aspect ratio that differs from that of the input image.
     A successful response contains the thumbnail image binary. If the request failed, the response contains an error code and a message to help determine what went wrong.
     Upon failure, the error code and an error message are returned. The error code could be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, InvalidThumbnailSize, NotSupportedImage, FailedToProcess, Timeout, or InternalServerError.
     *
     * @param width Width of the thumbnail, in pixels. It must be between 1 and 1024. Recommended minimum of 50.
     * @param height Height of the thumbnail, in pixels. It must be between 1 and 1024. Recommended minimum of 50.
     * @param url Publicly reachable URL of an image.
     * @param generateThumbnailOptionalParameter 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<InputStream> generateThumbnailAsync(int width, int height, String url, GenerateThumbnailOptionalParameter generateThumbnailOptionalParameter, final ServiceCallback<InputStream> serviceCallback) {
        return ServiceFuture.fromResponse(generateThumbnailWithServiceResponseAsync(width, height, url, generateThumbnailOptionalParameter), serviceCallback);
    }

    /**
     * This operation generates a thumbnail image with the user-specified width and height. By default, the service analyzes the image, identifies the region of interest (ROI), and generates smart cropping coordinates based on the ROI. Smart cropping helps when you specify an aspect ratio that differs from that of the input image.
     A successful response contains the thumbnail image binary. If the request failed, the response contains an error code and a message to help determine what went wrong.
     Upon failure, the error code and an error message are returned. The error code could be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, InvalidThumbnailSize, NotSupportedImage, FailedToProcess, Timeout, or InternalServerError.
     *
     * @param width Width of the thumbnail, in pixels. It must be between 1 and 1024. Recommended minimum of 50.
     * @param height Height of the thumbnail, in pixels. It must be between 1 and 1024. Recommended minimum of 50.
     * @param url Publicly reachable URL of an image.
     * @param generateThumbnailOptionalParameter 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 InputStream object
     */
    public Observable<InputStream> generateThumbnailAsync(int width, int height, String url, GenerateThumbnailOptionalParameter generateThumbnailOptionalParameter) {
        return generateThumbnailWithServiceResponseAsync(width, height, url, generateThumbnailOptionalParameter).map(new Func1<ServiceResponse<InputStream>, InputStream>() {
            @Override
            public InputStream call(ServiceResponse<InputStream> response) {
                return response.body();
            }
        });
    }

    /**
     * This operation generates a thumbnail image with the user-specified width and height. By default, the service analyzes the image, identifies the region of interest (ROI), and generates smart cropping coordinates based on the ROI. Smart cropping helps when you specify an aspect ratio that differs from that of the input image.
     A successful response contains the thumbnail image binary. If the request failed, the response contains an error code and a message to help determine what went wrong.
     Upon failure, the error code and an error message are returned. The error code could be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, InvalidThumbnailSize, NotSupportedImage, FailedToProcess, Timeout, or InternalServerError.
     *
     * @param width Width of the thumbnail, in pixels. It must be between 1 and 1024. Recommended minimum of 50.
     * @param height Height of the thumbnail, in pixels. It must be between 1 and 1024. Recommended minimum of 50.
     * @param url Publicly reachable URL of an image.
     * @param generateThumbnailOptionalParameter 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 InputStream object
     */
    public Observable<ServiceResponse<InputStream>> generateThumbnailWithServiceResponseAsync(int width, int height, String url, GenerateThumbnailOptionalParameter generateThumbnailOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (url == null) {
            throw new IllegalArgumentException("Parameter url is required and cannot be null.");
        }
        final Boolean smartCropping = generateThumbnailOptionalParameter != null ? generateThumbnailOptionalParameter.smartCropping() : null;
        final String modelVersion = generateThumbnailOptionalParameter != null ? generateThumbnailOptionalParameter.modelVersion() : null;

        return generateThumbnailWithServiceResponseAsync(width, height, url, smartCropping, modelVersion);
    }

    /**
     * This operation generates a thumbnail image with the user-specified width and height. By default, the service analyzes the image, identifies the region of interest (ROI), and generates smart cropping coordinates based on the ROI. Smart cropping helps when you specify an aspect ratio that differs from that of the input image.
     A successful response contains the thumbnail image binary. If the request failed, the response contains an error code and a message to help determine what went wrong.
     Upon failure, the error code and an error message are returned. The error code could be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, InvalidThumbnailSize, NotSupportedImage, FailedToProcess, Timeout, or InternalServerError.
     *
     * @param width Width of the thumbnail, in pixels. It must be between 1 and 1024. Recommended minimum of 50.
     * @param height Height of the thumbnail, in pixels. It must be between 1 and 1024. Recommended minimum of 50.
     * @param url Publicly reachable URL of an image.
     * @param smartCropping Boolean flag for enabling smart cropping.
     * @param modelVersion Optional parameter to specify the version of the AI model. Accepted values are: "latest", "2021-04-01". Defaults to "latest".
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the InputStream object
     */
    public Observable<ServiceResponse<InputStream>> generateThumbnailWithServiceResponseAsync(int width, int height, String url, Boolean smartCropping, String modelVersion) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (url == null) {
            throw new IllegalArgumentException("Parameter url is required and cannot be null.");
        }
        ImageUrl imageUrl = new ImageUrl();
        imageUrl.withUrl(url);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.generateThumbnail(width, height, smartCropping, modelVersion, this.client.acceptLanguage(), imageUrl, 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 = generateThumbnailDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<InputStream> generateThumbnailDelegate(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);
    }

    @Override
    public ComputerVisionGenerateThumbnailParameters generateThumbnail() {
        return new ComputerVisionGenerateThumbnailParameters(this);
    }

    /**
     * Internal class implementing ComputerVisionGenerateThumbnailDefinition.
     */
    class ComputerVisionGenerateThumbnailParameters implements ComputerVisionGenerateThumbnailDefinition {
        private ComputerVisionImpl parent;
        private int width;
        private int height;
        private String url;
        private Boolean smartCropping;
        private String modelVersion;

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

        @Override
        public ComputerVisionGenerateThumbnailParameters withWidth(int width) {
            this.width = width;
            return this;
        }

        @Override
        public ComputerVisionGenerateThumbnailParameters withHeight(int height) {
            this.height = height;
            return this;
        }

        @Override
        public ComputerVisionGenerateThumbnailParameters withUrl(String url) {
            this.url = url;
            return this;
        }

        @Override
        public ComputerVisionGenerateThumbnailParameters withSmartCropping(Boolean smartCropping) {
            this.smartCropping = smartCropping;
            return this;
        }

        @Override
        public ComputerVisionGenerateThumbnailParameters withModelVersion(String modelVersion) {
            this.modelVersion = modelVersion;
            return this;
        }

        @Override
        public InputStream execute() {
        return generateThumbnailWithServiceResponseAsync(width, height, url, smartCropping, modelVersion).toBlocking().single().body();
    }

        @Override
        public Observable<InputStream> executeAsync() {
            return generateThumbnailWithServiceResponseAsync(width, height, url, smartCropping, modelVersion).map(new Func1<ServiceResponse<InputStream>, InputStream>() {
                @Override
                public InputStream call(ServiceResponse<InputStream> response) {
                    return response.body();
                }
            });
        }
    }


    /**
     * This operation generates a list of words, or tags, that are relevant to the content of the supplied image. The Computer Vision API can return tags based on objects, living beings, scenery or actions found in images. Unlike categories, tags are not organized according to a hierarchical classification system, but correspond to image content. Tags may contain hints to avoid ambiguity or provide context, for example the tag "ascomycete" may be accompanied by the hint "fungus".
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param url Publicly reachable URL of an image.
     * @param tagImageOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ComputerVisionErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the TagResult object if successful.
     */
    public TagResult tagImage(String url, TagImageOptionalParameter tagImageOptionalParameter) {
        return tagImageWithServiceResponseAsync(url, tagImageOptionalParameter).toBlocking().single().body();
    }

    /**
     * This operation generates a list of words, or tags, that are relevant to the content of the supplied image. The Computer Vision API can return tags based on objects, living beings, scenery or actions found in images. Unlike categories, tags are not organized according to a hierarchical classification system, but correspond to image content. Tags may contain hints to avoid ambiguity or provide context, for example the tag "ascomycete" may be accompanied by the hint "fungus".
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param url Publicly reachable URL of an image.
     * @param tagImageOptionalParameter 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<TagResult> tagImageAsync(String url, TagImageOptionalParameter tagImageOptionalParameter, final ServiceCallback<TagResult> serviceCallback) {
        return ServiceFuture.fromResponse(tagImageWithServiceResponseAsync(url, tagImageOptionalParameter), serviceCallback);
    }

    /**
     * This operation generates a list of words, or tags, that are relevant to the content of the supplied image. The Computer Vision API can return tags based on objects, living beings, scenery or actions found in images. Unlike categories, tags are not organized according to a hierarchical classification system, but correspond to image content. Tags may contain hints to avoid ambiguity or provide context, for example the tag "ascomycete" may be accompanied by the hint "fungus".
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param url Publicly reachable URL of an image.
     * @param tagImageOptionalParameter 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 TagResult object
     */
    public Observable<TagResult> tagImageAsync(String url, TagImageOptionalParameter tagImageOptionalParameter) {
        return tagImageWithServiceResponseAsync(url, tagImageOptionalParameter).map(new Func1<ServiceResponse<TagResult>, TagResult>() {
            @Override
            public TagResult call(ServiceResponse<TagResult> response) {
                return response.body();
            }
        });
    }

    /**
     * This operation generates a list of words, or tags, that are relevant to the content of the supplied image. The Computer Vision API can return tags based on objects, living beings, scenery or actions found in images. Unlike categories, tags are not organized according to a hierarchical classification system, but correspond to image content. Tags may contain hints to avoid ambiguity or provide context, for example the tag "ascomycete" may be accompanied by the hint "fungus".
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param url Publicly reachable URL of an image.
     * @param tagImageOptionalParameter 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 TagResult object
     */
    public Observable<ServiceResponse<TagResult>> tagImageWithServiceResponseAsync(String url, TagImageOptionalParameter tagImageOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (url == null) {
            throw new IllegalArgumentException("Parameter url is required and cannot be null.");
        }
        final String language = tagImageOptionalParameter != null ? tagImageOptionalParameter.language() : null;
        final String modelVersion = tagImageOptionalParameter != null ? tagImageOptionalParameter.modelVersion() : null;

        return tagImageWithServiceResponseAsync(url, language, modelVersion);
    }

    /**
     * This operation generates a list of words, or tags, that are relevant to the content of the supplied image. The Computer Vision API can return tags based on objects, living beings, scenery or actions found in images. Unlike categories, tags are not organized according to a hierarchical classification system, but correspond to image content. Tags may contain hints to avoid ambiguity or provide context, for example the tag "ascomycete" may be accompanied by the hint "fungus".
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param url Publicly reachable URL of an image.
     * @param language The desired language for output generation. If this parameter is not specified, the default value is &amp;quot;en&amp;quot;.Supported languages:en - English, Default. es - Spanish, ja - Japanese, pt - Portuguese, zh - Simplified Chinese. Possible values include: 'en', 'es', 'ja', 'pt', 'zh'
     * @param modelVersion Optional parameter to specify the version of the AI model. Accepted values are: "latest", "2021-04-01". Defaults to "latest".
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the TagResult object
     */
    public Observable<ServiceResponse<TagResult>> tagImageWithServiceResponseAsync(String url, String language, String modelVersion) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (url == null) {
            throw new IllegalArgumentException("Parameter url is required and cannot be null.");
        }
        ImageUrl imageUrl = new ImageUrl();
        imageUrl.withUrl(url);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.tagImage(language, modelVersion, this.client.acceptLanguage(), imageUrl, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<TagResult>>>() {
                @Override
                public Observable<ServiceResponse<TagResult>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<TagResult> clientResponse = tagImageDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public ComputerVisionTagImageParameters tagImage() {
        return new ComputerVisionTagImageParameters(this);
    }

    /**
     * Internal class implementing ComputerVisionTagImageDefinition.
     */
    class ComputerVisionTagImageParameters implements ComputerVisionTagImageDefinition {
        private ComputerVisionImpl parent;
        private String url;
        private String language;
        private String modelVersion;

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

        @Override
        public ComputerVisionTagImageParameters withUrl(String url) {
            this.url = url;
            return this;
        }

        @Override
        public ComputerVisionTagImageParameters withLanguage(String language) {
            this.language = language;
            return this;
        }

        @Override
        public ComputerVisionTagImageParameters withModelVersion(String modelVersion) {
            this.modelVersion = modelVersion;
            return this;
        }

        @Override
        public TagResult execute() {
        return tagImageWithServiceResponseAsync(url, language, modelVersion).toBlocking().single().body();
    }

        @Override
        public Observable<TagResult> executeAsync() {
            return tagImageWithServiceResponseAsync(url, language, modelVersion).map(new Func1<ServiceResponse<TagResult>, TagResult>() {
                @Override
                public TagResult call(ServiceResponse<TagResult> response) {
                    return response.body();
                }
            });
        }
    }


    /**
     * Optical Character Recognition (OCR) detects text in an image and extracts the recognized characters into a machine-usable character stream.
     Upon success, the OCR results will be returned.
     Upon failure, the error code together with an error message will be returned. The error code can be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage, NotSupportedLanguage, or InternalServerError.
     *
     * @param detectOrientation Whether detect the text orientation in the image. With detectOrientation=true the OCR service tries to detect the image orientation and correct it before further processing (e.g. if it's upside-down).
     * @param url Publicly reachable URL of an image.
     * @param recognizePrintedTextOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ComputerVisionErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the OcrResult object if successful.
     */
    public OcrResult recognizePrintedText(boolean detectOrientation, String url, RecognizePrintedTextOptionalParameter recognizePrintedTextOptionalParameter) {
        return recognizePrintedTextWithServiceResponseAsync(detectOrientation, url, recognizePrintedTextOptionalParameter).toBlocking().single().body();
    }

    /**
     * Optical Character Recognition (OCR) detects text in an image and extracts the recognized characters into a machine-usable character stream.
     Upon success, the OCR results will be returned.
     Upon failure, the error code together with an error message will be returned. The error code can be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage, NotSupportedLanguage, or InternalServerError.
     *
     * @param detectOrientation Whether detect the text orientation in the image. With detectOrientation=true the OCR service tries to detect the image orientation and correct it before further processing (e.g. if it's upside-down).
     * @param url Publicly reachable URL of an image.
     * @param recognizePrintedTextOptionalParameter 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<OcrResult> recognizePrintedTextAsync(boolean detectOrientation, String url, RecognizePrintedTextOptionalParameter recognizePrintedTextOptionalParameter, final ServiceCallback<OcrResult> serviceCallback) {
        return ServiceFuture.fromResponse(recognizePrintedTextWithServiceResponseAsync(detectOrientation, url, recognizePrintedTextOptionalParameter), serviceCallback);
    }

    /**
     * Optical Character Recognition (OCR) detects text in an image and extracts the recognized characters into a machine-usable character stream.
     Upon success, the OCR results will be returned.
     Upon failure, the error code together with an error message will be returned. The error code can be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage, NotSupportedLanguage, or InternalServerError.
     *
     * @param detectOrientation Whether detect the text orientation in the image. With detectOrientation=true the OCR service tries to detect the image orientation and correct it before further processing (e.g. if it's upside-down).
     * @param url Publicly reachable URL of an image.
     * @param recognizePrintedTextOptionalParameter 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 OcrResult object
     */
    public Observable<OcrResult> recognizePrintedTextAsync(boolean detectOrientation, String url, RecognizePrintedTextOptionalParameter recognizePrintedTextOptionalParameter) {
        return recognizePrintedTextWithServiceResponseAsync(detectOrientation, url, recognizePrintedTextOptionalParameter).map(new Func1<ServiceResponse<OcrResult>, OcrResult>() {
            @Override
            public OcrResult call(ServiceResponse<OcrResult> response) {
                return response.body();
            }
        });
    }

    /**
     * Optical Character Recognition (OCR) detects text in an image and extracts the recognized characters into a machine-usable character stream.
     Upon success, the OCR results will be returned.
     Upon failure, the error code together with an error message will be returned. The error code can be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage, NotSupportedLanguage, or InternalServerError.
     *
     * @param detectOrientation Whether detect the text orientation in the image. With detectOrientation=true the OCR service tries to detect the image orientation and correct it before further processing (e.g. if it's upside-down).
     * @param url Publicly reachable URL of an image.
     * @param recognizePrintedTextOptionalParameter 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 OcrResult object
     */
    public Observable<ServiceResponse<OcrResult>> recognizePrintedTextWithServiceResponseAsync(boolean detectOrientation, String url, RecognizePrintedTextOptionalParameter recognizePrintedTextOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (url == null) {
            throw new IllegalArgumentException("Parameter url is required and cannot be null.");
        }
        final OcrLanguages language = recognizePrintedTextOptionalParameter != null ? recognizePrintedTextOptionalParameter.language() : null;
        final String modelVersion = recognizePrintedTextOptionalParameter != null ? recognizePrintedTextOptionalParameter.modelVersion() : null;

        return recognizePrintedTextWithServiceResponseAsync(detectOrientation, url, language, modelVersion);
    }

    /**
     * Optical Character Recognition (OCR) detects text in an image and extracts the recognized characters into a machine-usable character stream.
     Upon success, the OCR results will be returned.
     Upon failure, the error code together with an error message will be returned. The error code can be one of InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage, NotSupportedLanguage, or InternalServerError.
     *
     * @param detectOrientation Whether detect the text orientation in the image. With detectOrientation=true the OCR service tries to detect the image orientation and correct it before further processing (e.g. if it's upside-down).
     * @param url Publicly reachable URL of an image.
     * @param language The BCP-47 language code of the text to be detected in the image. The default value is 'unk'. Possible values include: 'unk', 'zh-Hans', 'zh-Hant', 'cs', 'da', 'nl', 'en', 'fi', 'fr', 'de', 'el', 'hu', 'it', 'ja', 'ko', 'nb', 'pl', 'pt', 'ru', 'es', 'sv', 'tr', 'ar', 'ro', 'sr-Cyrl', 'sr-Latn', 'sk'
     * @param modelVersion Optional parameter to specify the version of the AI model. Accepted values are: "latest", "2021-04-01". Defaults to "latest".
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the OcrResult object
     */
    public Observable<ServiceResponse<OcrResult>> recognizePrintedTextWithServiceResponseAsync(boolean detectOrientation, String url, OcrLanguages language, String modelVersion) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (url == null) {
            throw new IllegalArgumentException("Parameter url is required and cannot be null.");
        }
        ImageUrl imageUrl = new ImageUrl();
        imageUrl.withUrl(url);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.recognizePrintedText(detectOrientation, language, modelVersion, this.client.acceptLanguage(), imageUrl, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<OcrResult>>>() {
                @Override
                public Observable<ServiceResponse<OcrResult>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<OcrResult> clientResponse = recognizePrintedTextDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public ComputerVisionRecognizePrintedTextParameters recognizePrintedText() {
        return new ComputerVisionRecognizePrintedTextParameters(this);
    }

    /**
     * Internal class implementing ComputerVisionRecognizePrintedTextDefinition.
     */
    class ComputerVisionRecognizePrintedTextParameters implements ComputerVisionRecognizePrintedTextDefinition {
        private ComputerVisionImpl parent;
        private boolean detectOrientation;
        private String url;
        private OcrLanguages language;
        private String modelVersion;

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

        @Override
        public ComputerVisionRecognizePrintedTextParameters withDetectOrientation(boolean detectOrientation) {
            this.detectOrientation = detectOrientation;
            return this;
        }

        @Override
        public ComputerVisionRecognizePrintedTextParameters withUrl(String url) {
            this.url = url;
            return this;
        }

        @Override
        public ComputerVisionRecognizePrintedTextParameters withLanguage(OcrLanguages language) {
            this.language = language;
            return this;
        }

        @Override
        public ComputerVisionRecognizePrintedTextParameters withModelVersion(String modelVersion) {
            this.modelVersion = modelVersion;
            return this;
        }

        @Override
        public OcrResult execute() {
        return recognizePrintedTextWithServiceResponseAsync(detectOrientation, url, language, modelVersion).toBlocking().single().body();
    }

        @Override
        public Observable<OcrResult> executeAsync() {
            return recognizePrintedTextWithServiceResponseAsync(detectOrientation, url, language, modelVersion).map(new Func1<ServiceResponse<OcrResult>, OcrResult>() {
                @Override
                public OcrResult call(ServiceResponse<OcrResult> response) {
                    return response.body();
                }
            });
        }
    }


    /**
     * This operation recognizes content within an image by applying a domain-specific model. The list of domain-specific models that are supported by the Computer Vision API can be retrieved using the /models GET request. Currently, the API provides following domain-specific models: celebrities, landmarks.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON.
     If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param model The domain-specific content to recognize.
     * @param url Publicly reachable URL of an image.
     * @param analyzeImageByDomainOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ComputerVisionErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the DomainModelResults object if successful.
     */
    public DomainModelResults analyzeImageByDomain(String model, String url, AnalyzeImageByDomainOptionalParameter analyzeImageByDomainOptionalParameter) {
        return analyzeImageByDomainWithServiceResponseAsync(model, url, analyzeImageByDomainOptionalParameter).toBlocking().single().body();
    }

    /**
     * This operation recognizes content within an image by applying a domain-specific model. The list of domain-specific models that are supported by the Computer Vision API can be retrieved using the /models GET request. Currently, the API provides following domain-specific models: celebrities, landmarks.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON.
     If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param model The domain-specific content to recognize.
     * @param url Publicly reachable URL of an image.
     * @param analyzeImageByDomainOptionalParameter 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<DomainModelResults> analyzeImageByDomainAsync(String model, String url, AnalyzeImageByDomainOptionalParameter analyzeImageByDomainOptionalParameter, final ServiceCallback<DomainModelResults> serviceCallback) {
        return ServiceFuture.fromResponse(analyzeImageByDomainWithServiceResponseAsync(model, url, analyzeImageByDomainOptionalParameter), serviceCallback);
    }

    /**
     * This operation recognizes content within an image by applying a domain-specific model. The list of domain-specific models that are supported by the Computer Vision API can be retrieved using the /models GET request. Currently, the API provides following domain-specific models: celebrities, landmarks.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON.
     If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param model The domain-specific content to recognize.
     * @param url Publicly reachable URL of an image.
     * @param analyzeImageByDomainOptionalParameter 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 DomainModelResults object
     */
    public Observable<DomainModelResults> analyzeImageByDomainAsync(String model, String url, AnalyzeImageByDomainOptionalParameter analyzeImageByDomainOptionalParameter) {
        return analyzeImageByDomainWithServiceResponseAsync(model, url, analyzeImageByDomainOptionalParameter).map(new Func1<ServiceResponse<DomainModelResults>, DomainModelResults>() {
            @Override
            public DomainModelResults call(ServiceResponse<DomainModelResults> response) {
                return response.body();
            }
        });
    }

    /**
     * This operation recognizes content within an image by applying a domain-specific model. The list of domain-specific models that are supported by the Computer Vision API can be retrieved using the /models GET request. Currently, the API provides following domain-specific models: celebrities, landmarks.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON.
     If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param model The domain-specific content to recognize.
     * @param url Publicly reachable URL of an image.
     * @param analyzeImageByDomainOptionalParameter 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 DomainModelResults object
     */
    public Observable<ServiceResponse<DomainModelResults>> analyzeImageByDomainWithServiceResponseAsync(String model, String url, AnalyzeImageByDomainOptionalParameter analyzeImageByDomainOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (model == null) {
            throw new IllegalArgumentException("Parameter model is required and cannot be null.");
        }
        if (url == null) {
            throw new IllegalArgumentException("Parameter url is required and cannot be null.");
        }
        final String language = analyzeImageByDomainOptionalParameter != null ? analyzeImageByDomainOptionalParameter.language() : null;
        final String modelVersion = analyzeImageByDomainOptionalParameter != null ? analyzeImageByDomainOptionalParameter.modelVersion() : null;

        return analyzeImageByDomainWithServiceResponseAsync(model, url, language, modelVersion);
    }

    /**
     * This operation recognizes content within an image by applying a domain-specific model. The list of domain-specific models that are supported by the Computer Vision API can be retrieved using the /models GET request. Currently, the API provides following domain-specific models: celebrities, landmarks.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON.
     If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param model The domain-specific content to recognize.
     * @param url Publicly reachable URL of an image.
     * @param language The desired language for output generation. If this parameter is not specified, the default value is &amp;quot;en&amp;quot;.Supported languages:en - English, Default. es - Spanish, ja - Japanese, pt - Portuguese, zh - Simplified Chinese. Possible values include: 'en', 'es', 'ja', 'pt', 'zh'
     * @param modelVersion Optional parameter to specify the version of the AI model. Accepted values are: "latest", "2021-04-01". Defaults to "latest".
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DomainModelResults object
     */
    public Observable<ServiceResponse<DomainModelResults>> analyzeImageByDomainWithServiceResponseAsync(String model, String url, String language, String modelVersion) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (model == null) {
            throw new IllegalArgumentException("Parameter model is required and cannot be null.");
        }
        if (url == null) {
            throw new IllegalArgumentException("Parameter url is required and cannot be null.");
        }
        ImageUrl imageUrl = new ImageUrl();
        imageUrl.withUrl(url);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.analyzeImageByDomain(model, language, modelVersion, this.client.acceptLanguage(), imageUrl, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<DomainModelResults>>>() {
                @Override
                public Observable<ServiceResponse<DomainModelResults>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<DomainModelResults> clientResponse = analyzeImageByDomainDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public ComputerVisionAnalyzeImageByDomainParameters analyzeImageByDomain() {
        return new ComputerVisionAnalyzeImageByDomainParameters(this);
    }

    /**
     * Internal class implementing ComputerVisionAnalyzeImageByDomainDefinition.
     */
    class ComputerVisionAnalyzeImageByDomainParameters implements ComputerVisionAnalyzeImageByDomainDefinition {
        private ComputerVisionImpl parent;
        private String model;
        private String url;
        private String language;
        private String modelVersion;

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

        @Override
        public ComputerVisionAnalyzeImageByDomainParameters withModel(String model) {
            this.model = model;
            return this;
        }

        @Override
        public ComputerVisionAnalyzeImageByDomainParameters withUrl(String url) {
            this.url = url;
            return this;
        }

        @Override
        public ComputerVisionAnalyzeImageByDomainParameters withLanguage(String language) {
            this.language = language;
            return this;
        }

        @Override
        public ComputerVisionAnalyzeImageByDomainParameters withModelVersion(String modelVersion) {
            this.modelVersion = modelVersion;
            return this;
        }

        @Override
        public DomainModelResults execute() {
        return analyzeImageByDomainWithServiceResponseAsync(model, url, language, modelVersion).toBlocking().single().body();
    }

        @Override
        public Observable<DomainModelResults> executeAsync() {
            return analyzeImageByDomainWithServiceResponseAsync(model, url, language, modelVersion).map(new Func1<ServiceResponse<DomainModelResults>, DomainModelResults>() {
                @Override
                public DomainModelResults call(ServiceResponse<DomainModelResults> response) {
                    return response.body();
                }
            });
        }
    }

    /**
     * This operation returns the list of domain-specific models that are supported by the Computer Vision API. Currently, the API supports following domain-specific models: celebrity recognizer, landmark recognizer.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ComputerVisionErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the ListModelsResult object if successful.
     */
    public ListModelsResult listModels() {
        return listModelsWithServiceResponseAsync().toBlocking().single().body();
    }

    /**
     * This operation returns the list of domain-specific models that are supported by the Computer Vision API. Currently, the API supports following domain-specific models: celebrity recognizer, landmark recognizer.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @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<ListModelsResult> listModelsAsync(final ServiceCallback<ListModelsResult> serviceCallback) {
        return ServiceFuture.fromResponse(listModelsWithServiceResponseAsync(), serviceCallback);
    }

    /**
     * This operation returns the list of domain-specific models that are supported by the Computer Vision API. Currently, the API supports following domain-specific models: celebrity recognizer, landmark recognizer.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the ListModelsResult object
     */
    public Observable<ListModelsResult> listModelsAsync() {
        return listModelsWithServiceResponseAsync().map(new Func1<ServiceResponse<ListModelsResult>, ListModelsResult>() {
            @Override
            public ListModelsResult call(ServiceResponse<ListModelsResult> response) {
                return response.body();
            }
        });
    }

    /**
     * This operation returns the list of domain-specific models that are supported by the Computer Vision API. Currently, the API supports following domain-specific models: celebrity recognizer, landmark recognizer.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the ListModelsResult object
     */
    public Observable<ServiceResponse<ListModelsResult>> listModelsWithServiceResponseAsync() {
        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.listModels(this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<ListModelsResult>>>() {
                @Override
                public Observable<ServiceResponse<ListModelsResult>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<ListModelsResult> clientResponse = listModelsDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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


    /**
     * Performs object detection on the specified image.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param url Publicly reachable URL of an image.
     * @param detectObjectsOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ComputerVisionErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the DetectResult object if successful.
     */
    public DetectResult detectObjects(String url, DetectObjectsOptionalParameter detectObjectsOptionalParameter) {
        return detectObjectsWithServiceResponseAsync(url, detectObjectsOptionalParameter).toBlocking().single().body();
    }

    /**
     * Performs object detection on the specified image.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param url Publicly reachable URL of an image.
     * @param detectObjectsOptionalParameter 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<DetectResult> detectObjectsAsync(String url, DetectObjectsOptionalParameter detectObjectsOptionalParameter, final ServiceCallback<DetectResult> serviceCallback) {
        return ServiceFuture.fromResponse(detectObjectsWithServiceResponseAsync(url, detectObjectsOptionalParameter), serviceCallback);
    }

    /**
     * Performs object detection on the specified image.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param url Publicly reachable URL of an image.
     * @param detectObjectsOptionalParameter 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 DetectResult object
     */
    public Observable<DetectResult> detectObjectsAsync(String url, DetectObjectsOptionalParameter detectObjectsOptionalParameter) {
        return detectObjectsWithServiceResponseAsync(url, detectObjectsOptionalParameter).map(new Func1<ServiceResponse<DetectResult>, DetectResult>() {
            @Override
            public DetectResult call(ServiceResponse<DetectResult> response) {
                return response.body();
            }
        });
    }

    /**
     * Performs object detection on the specified image.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param url Publicly reachable URL of an image.
     * @param detectObjectsOptionalParameter 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 DetectResult object
     */
    public Observable<ServiceResponse<DetectResult>> detectObjectsWithServiceResponseAsync(String url, DetectObjectsOptionalParameter detectObjectsOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (url == null) {
            throw new IllegalArgumentException("Parameter url is required and cannot be null.");
        }
        final String modelVersion = detectObjectsOptionalParameter != null ? detectObjectsOptionalParameter.modelVersion() : null;

        return detectObjectsWithServiceResponseAsync(url, modelVersion);
    }

    /**
     * Performs object detection on the specified image.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param url Publicly reachable URL of an image.
     * @param modelVersion Optional parameter to specify the version of the AI model. Accepted values are: "latest", "2021-04-01". Defaults to "latest".
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DetectResult object
     */
    public Observable<ServiceResponse<DetectResult>> detectObjectsWithServiceResponseAsync(String url, String modelVersion) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (url == null) {
            throw new IllegalArgumentException("Parameter url is required and cannot be null.");
        }
        ImageUrl imageUrl = new ImageUrl();
        imageUrl.withUrl(url);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.detectObjects(modelVersion, this.client.acceptLanguage(), imageUrl, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<DetectResult>>>() {
                @Override
                public Observable<ServiceResponse<DetectResult>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<DetectResult> clientResponse = detectObjectsDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public ComputerVisionDetectObjectsParameters detectObjects() {
        return new ComputerVisionDetectObjectsParameters(this);
    }

    /**
     * Internal class implementing ComputerVisionDetectObjectsDefinition.
     */
    class ComputerVisionDetectObjectsParameters implements ComputerVisionDetectObjectsDefinition {
        private ComputerVisionImpl parent;
        private String url;
        private String modelVersion;

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

        @Override
        public ComputerVisionDetectObjectsParameters withUrl(String url) {
            this.url = url;
            return this;
        }

        @Override
        public ComputerVisionDetectObjectsParameters withModelVersion(String modelVersion) {
            this.modelVersion = modelVersion;
            return this;
        }

        @Override
        public DetectResult execute() {
        return detectObjectsWithServiceResponseAsync(url, modelVersion).toBlocking().single().body();
    }

        @Override
        public Observable<DetectResult> executeAsync() {
            return detectObjectsWithServiceResponseAsync(url, modelVersion).map(new Func1<ServiceResponse<DetectResult>, DetectResult>() {
                @Override
                public DetectResult call(ServiceResponse<DetectResult> response) {
                    return response.body();
                }
            });
        }
    }


    /**
     * This operation generates a description of an image in human readable language with complete sentences. The description is based on a collection of content tags, which are also returned by the operation. More than one description can be generated for each image. Descriptions are ordered by their confidence score. Descriptions may include results from celebrity and landmark domain models, if applicable.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param url Publicly reachable URL of an image.
     * @param describeImageOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ComputerVisionErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the ImageDescription object if successful.
     */
    public ImageDescription describeImage(String url, DescribeImageOptionalParameter describeImageOptionalParameter) {
        return describeImageWithServiceResponseAsync(url, describeImageOptionalParameter).toBlocking().single().body();
    }

    /**
     * This operation generates a description of an image in human readable language with complete sentences. The description is based on a collection of content tags, which are also returned by the operation. More than one description can be generated for each image. Descriptions are ordered by their confidence score. Descriptions may include results from celebrity and landmark domain models, if applicable.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param url Publicly reachable URL of an image.
     * @param describeImageOptionalParameter 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<ImageDescription> describeImageAsync(String url, DescribeImageOptionalParameter describeImageOptionalParameter, final ServiceCallback<ImageDescription> serviceCallback) {
        return ServiceFuture.fromResponse(describeImageWithServiceResponseAsync(url, describeImageOptionalParameter), serviceCallback);
    }

    /**
     * This operation generates a description of an image in human readable language with complete sentences. The description is based on a collection of content tags, which are also returned by the operation. More than one description can be generated for each image. Descriptions are ordered by their confidence score. Descriptions may include results from celebrity and landmark domain models, if applicable.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param url Publicly reachable URL of an image.
     * @param describeImageOptionalParameter 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 ImageDescription object
     */
    public Observable<ImageDescription> describeImageAsync(String url, DescribeImageOptionalParameter describeImageOptionalParameter) {
        return describeImageWithServiceResponseAsync(url, describeImageOptionalParameter).map(new Func1<ServiceResponse<ImageDescription>, ImageDescription>() {
            @Override
            public ImageDescription call(ServiceResponse<ImageDescription> response) {
                return response.body();
            }
        });
    }

    /**
     * This operation generates a description of an image in human readable language with complete sentences. The description is based on a collection of content tags, which are also returned by the operation. More than one description can be generated for each image. Descriptions are ordered by their confidence score. Descriptions may include results from celebrity and landmark domain models, if applicable.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param url Publicly reachable URL of an image.
     * @param describeImageOptionalParameter 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 ImageDescription object
     */
    public Observable<ServiceResponse<ImageDescription>> describeImageWithServiceResponseAsync(String url, DescribeImageOptionalParameter describeImageOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (url == null) {
            throw new IllegalArgumentException("Parameter url is required and cannot be null.");
        }
        final Integer maxCandidates = describeImageOptionalParameter != null ? describeImageOptionalParameter.maxCandidates() : null;
        final String language = describeImageOptionalParameter != null ? describeImageOptionalParameter.language() : null;
        final List<DescriptionExclude> descriptionExclude = describeImageOptionalParameter != null ? describeImageOptionalParameter.descriptionExclude() : null;
        final String modelVersion = describeImageOptionalParameter != null ? describeImageOptionalParameter.modelVersion() : null;

        return describeImageWithServiceResponseAsync(url, maxCandidates, language, descriptionExclude, modelVersion);
    }

    /**
     * This operation generates a description of an image in human readable language with complete sentences. The description is based on a collection of content tags, which are also returned by the operation. More than one description can be generated for each image. Descriptions are ordered by their confidence score. Descriptions may include results from celebrity and landmark domain models, if applicable.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param url Publicly reachable URL of an image.
     * @param maxCandidates Maximum number of candidate descriptions to be returned.  The default is 1.
     * @param language The desired language for output generation. If this parameter is not specified, the default value is &amp;quot;en&amp;quot;.Supported languages:en - English, Default. es - Spanish, ja - Japanese, pt - Portuguese, zh - Simplified Chinese. Possible values include: 'en', 'es', 'ja', 'pt', 'zh'
     * @param descriptionExclude Turn off specified domain models when generating the description.
     * @param modelVersion Optional parameter to specify the version of the AI model. Accepted values are: "latest", "2021-04-01". Defaults to "latest".
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the ImageDescription object
     */
    public Observable<ServiceResponse<ImageDescription>> describeImageWithServiceResponseAsync(String url, Integer maxCandidates, String language, List<DescriptionExclude> descriptionExclude, String modelVersion) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (url == null) {
            throw new IllegalArgumentException("Parameter url is required and cannot be null.");
        }
        Validator.validate(descriptionExclude);
        ImageUrl imageUrl = new ImageUrl();
        imageUrl.withUrl(url);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        String descriptionExcludeConverted = this.client.serializerAdapter().serializeList(descriptionExclude, CollectionFormat.CSV);
        return service.describeImage(maxCandidates, language, descriptionExcludeConverted, modelVersion, this.client.acceptLanguage(), imageUrl, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<ImageDescription>>>() {
                @Override
                public Observable<ServiceResponse<ImageDescription>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<ImageDescription> clientResponse = describeImageDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public ComputerVisionDescribeImageParameters describeImage() {
        return new ComputerVisionDescribeImageParameters(this);
    }

    /**
     * Internal class implementing ComputerVisionDescribeImageDefinition.
     */
    class ComputerVisionDescribeImageParameters implements ComputerVisionDescribeImageDefinition {
        private ComputerVisionImpl parent;
        private String url;
        private Integer maxCandidates;
        private String language;
        private List<DescriptionExclude> descriptionExclude;
        private String modelVersion;

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

        @Override
        public ComputerVisionDescribeImageParameters withUrl(String url) {
            this.url = url;
            return this;
        }

        @Override
        public ComputerVisionDescribeImageParameters withMaxCandidates(Integer maxCandidates) {
            this.maxCandidates = maxCandidates;
            return this;
        }

        @Override
        public ComputerVisionDescribeImageParameters withLanguage(String language) {
            this.language = language;
            return this;
        }

        @Override
        public ComputerVisionDescribeImageParameters withDescriptionExclude(List<DescriptionExclude> descriptionExclude) {
            this.descriptionExclude = descriptionExclude;
            return this;
        }

        @Override
        public ComputerVisionDescribeImageParameters withModelVersion(String modelVersion) {
            this.modelVersion = modelVersion;
            return this;
        }

        @Override
        public ImageDescription execute() {
        return describeImageWithServiceResponseAsync(url, maxCandidates, language, descriptionExclude, modelVersion).toBlocking().single().body();
    }

        @Override
        public Observable<ImageDescription> executeAsync() {
            return describeImageWithServiceResponseAsync(url, maxCandidates, language, descriptionExclude, modelVersion).map(new Func1<ServiceResponse<ImageDescription>, ImageDescription>() {
                @Override
                public ImageDescription call(ServiceResponse<ImageDescription> response) {
                    return response.body();
                }
            });
        }
    }


    /**
     * This operation extracts a rich set of visual features based on the image content.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL. Within your request, there is an optional parameter to allow you to choose which features to return. By default, image categories are returned in the response.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param url Publicly reachable URL of an image.
     * @param analyzeImageOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ComputerVisionErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the ImageAnalysis object if successful.
     */
    public ImageAnalysis analyzeImage(String url, AnalyzeImageOptionalParameter analyzeImageOptionalParameter) {
        return analyzeImageWithServiceResponseAsync(url, analyzeImageOptionalParameter).toBlocking().single().body();
    }

    /**
     * This operation extracts a rich set of visual features based on the image content.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL. Within your request, there is an optional parameter to allow you to choose which features to return. By default, image categories are returned in the response.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param url Publicly reachable URL of an image.
     * @param analyzeImageOptionalParameter 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<ImageAnalysis> analyzeImageAsync(String url, AnalyzeImageOptionalParameter analyzeImageOptionalParameter, final ServiceCallback<ImageAnalysis> serviceCallback) {
        return ServiceFuture.fromResponse(analyzeImageWithServiceResponseAsync(url, analyzeImageOptionalParameter), serviceCallback);
    }

    /**
     * This operation extracts a rich set of visual features based on the image content.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL. Within your request, there is an optional parameter to allow you to choose which features to return. By default, image categories are returned in the response.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param url Publicly reachable URL of an image.
     * @param analyzeImageOptionalParameter 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 ImageAnalysis object
     */
    public Observable<ImageAnalysis> analyzeImageAsync(String url, AnalyzeImageOptionalParameter analyzeImageOptionalParameter) {
        return analyzeImageWithServiceResponseAsync(url, analyzeImageOptionalParameter).map(new Func1<ServiceResponse<ImageAnalysis>, ImageAnalysis>() {
            @Override
            public ImageAnalysis call(ServiceResponse<ImageAnalysis> response) {
                return response.body();
            }
        });
    }

    /**
     * This operation extracts a rich set of visual features based on the image content.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL. Within your request, there is an optional parameter to allow you to choose which features to return. By default, image categories are returned in the response.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param url Publicly reachable URL of an image.
     * @param analyzeImageOptionalParameter 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 ImageAnalysis object
     */
    public Observable<ServiceResponse<ImageAnalysis>> analyzeImageWithServiceResponseAsync(String url, AnalyzeImageOptionalParameter analyzeImageOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (url == null) {
            throw new IllegalArgumentException("Parameter url is required and cannot be null.");
        }
        final List<VisualFeatureTypes> visualFeatures = analyzeImageOptionalParameter != null ? analyzeImageOptionalParameter.visualFeatures() : null;
        final List<Details> details = analyzeImageOptionalParameter != null ? analyzeImageOptionalParameter.details() : null;
        final String language = analyzeImageOptionalParameter != null ? analyzeImageOptionalParameter.language() : null;
        final List<DescriptionExclude> descriptionExclude = analyzeImageOptionalParameter != null ? analyzeImageOptionalParameter.descriptionExclude() : null;
        final String modelVersion = analyzeImageOptionalParameter != null ? analyzeImageOptionalParameter.modelVersion() : null;

        return analyzeImageWithServiceResponseAsync(url, visualFeatures, details, language, descriptionExclude, modelVersion);
    }

    /**
     * This operation extracts a rich set of visual features based on the image content.
     Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL. Within your request, there is an optional parameter to allow you to choose which features to return. By default, image categories are returned in the response.
     A successful response will be returned in JSON. If the request failed, the response will contain an error code and a message to help understand what went wrong.
     *
     * @param url Publicly reachable URL of an image.
     * @param visualFeatures A string indicating what visual feature types to return. Multiple values should be comma-separated. Valid visual feature types include: Categories - categorizes image content according to a taxonomy defined in documentation. Tags - tags the image with a detailed list of words related to the image content. Description - describes the image content with a complete English sentence. Faces - detects if faces are present. If present, generate coordinates, gender and age. ImageType - detects if image is clipart or a line drawing. Color - determines the accent color, dominant color, and whether an image is black&amp;white. Adult - detects if the image is pornographic in nature (depicts nudity or a sex act), or is gory (depicts extreme violence or blood). Sexually suggestive content (aka racy content) is also detected. Objects - detects various objects within an image, including the approximate location. The Objects argument is only available in English. Brands - detects various brands within an image, including the approximate location. The Brands argument is only available in English.
     * @param details A string indicating which domain-specific details to return. Multiple values should be comma-separated. Valid visual feature types include: Celebrities - identifies celebrities if detected in the image, Landmarks - identifies notable landmarks in the image.
     * @param language The desired language for output generation. If this parameter is not specified, the default value is &amp;quot;en&amp;quot;.Supported languages:en - English, Default. es - Spanish, ja - Japanese, pt - Portuguese, zh - Simplified Chinese. Possible values include: 'en', 'es', 'ja', 'pt', 'zh'
     * @param descriptionExclude Turn off specified domain models when generating the description.
     * @param modelVersion Optional parameter to specify the version of the AI model. Accepted values are: "latest", "2021-04-01". Defaults to "latest".
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the ImageAnalysis object
     */
    public Observable<ServiceResponse<ImageAnalysis>> analyzeImageWithServiceResponseAsync(String url, List<VisualFeatureTypes> visualFeatures, List<Details> details, String language, List<DescriptionExclude> descriptionExclude, String modelVersion) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (url == null) {
            throw new IllegalArgumentException("Parameter url is required and cannot be null.");
        }
        Validator.validate(visualFeatures);
        Validator.validate(details);
        Validator.validate(descriptionExclude);
        ImageUrl imageUrl = new ImageUrl();
        imageUrl.withUrl(url);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        String visualFeaturesConverted = this.client.serializerAdapter().serializeList(visualFeatures, CollectionFormat.CSV);
        String detailsConverted = this.client.serializerAdapter().serializeList(details, CollectionFormat.CSV);
        String descriptionExcludeConverted = this.client.serializerAdapter().serializeList(descriptionExclude, CollectionFormat.CSV);
        return service.analyzeImage(visualFeaturesConverted, detailsConverted, language, descriptionExcludeConverted, modelVersion, this.client.acceptLanguage(), imageUrl, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<ImageAnalysis>>>() {
                @Override
                public Observable<ServiceResponse<ImageAnalysis>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<ImageAnalysis> clientResponse = analyzeImageDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    @Override
    public ComputerVisionAnalyzeImageParameters analyzeImage() {
        return new ComputerVisionAnalyzeImageParameters(this);
    }

    /**
     * Internal class implementing ComputerVisionAnalyzeImageDefinition.
     */
    class ComputerVisionAnalyzeImageParameters implements ComputerVisionAnalyzeImageDefinition {
        private ComputerVisionImpl parent;
        private String url;
        private List<VisualFeatureTypes> visualFeatures;
        private List<Details> details;
        private String language;
        private List<DescriptionExclude> descriptionExclude;
        private String modelVersion;

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

        @Override
        public ComputerVisionAnalyzeImageParameters withUrl(String url) {
            this.url = url;
            return this;
        }

        @Override
        public ComputerVisionAnalyzeImageParameters withVisualFeatures(List<VisualFeatureTypes> visualFeatures) {
            this.visualFeatures = visualFeatures;
            return this;
        }

        @Override
        public ComputerVisionAnalyzeImageParameters withDetails(List<Details> details) {
            this.details = details;
            return this;
        }

        @Override
        public ComputerVisionAnalyzeImageParameters withLanguage(String language) {
            this.language = language;
            return this;
        }

        @Override
        public ComputerVisionAnalyzeImageParameters withDescriptionExclude(List<DescriptionExclude> descriptionExclude) {
            this.descriptionExclude = descriptionExclude;
            return this;
        }

        @Override
        public ComputerVisionAnalyzeImageParameters withModelVersion(String modelVersion) {
            this.modelVersion = modelVersion;
            return this;
        }

        @Override
        public ImageAnalysis execute() {
        return analyzeImageWithServiceResponseAsync(url, visualFeatures, details, language, descriptionExclude, modelVersion).toBlocking().single().body();
    }

        @Override
        public Observable<ImageAnalysis> executeAsync() {
            return analyzeImageWithServiceResponseAsync(url, visualFeatures, details, language, descriptionExclude, modelVersion).map(new Func1<ServiceResponse<ImageAnalysis>, ImageAnalysis>() {
                @Override
                public ImageAnalysis call(ServiceResponse<ImageAnalysis> response) {
                    return response.body();
                }
            });
        }
    }

}
