microsoft-bonsai-api-main/Java/com.microsoft.bonsai.api/simulator/generated/src/main/java/com/microsoft/bonsai/simulatorapi/implementation/SessionsImpl.java
/**
 * Code generated by Microsoft (R) AutoRest Code Generator.
 * Changes may cause incorrect behavior and will be lost if the code is
 * regenerated.
 */

package com.microsoft.bonsai.simulatorapi.implementation;

import retrofit2.Retrofit;
import com.microsoft.bonsai.simulatorapi.Sessions;
import com.google.common.reflect.TypeToken;
import com.microsoft.bonsai.simulatorapi.models.Event;
import com.microsoft.bonsai.simulatorapi.models.ProblemDetailsException;
import com.microsoft.bonsai.simulatorapi.models.SimulatorInterface;
import com.microsoft.bonsai.simulatorapi.models.SimulatorSessionResponse;
import com.microsoft.bonsai.simulatorapi.models.SimulatorSessionSummary;
import com.microsoft.bonsai.simulatorapi.models.SimulatorState;
import com.microsoft.rest.ServiceCallback;
import com.microsoft.rest.ServiceFuture;
import com.microsoft.rest.ServiceResponse;
import com.microsoft.rest.Validator;
import java.io.IOException;
import java.util.List;
import okhttp3.ResponseBody;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Headers;
import retrofit2.http.HTTP;
import retrofit2.http.Path;
import retrofit2.http.POST;
import retrofit2.http.Query;
import retrofit2.Response;
import rx.functions.Func1;
import rx.Observable;

/**
 * An instance of this class provides access to all the operations defined
 * in Sessions.
 */
public class SessionsImpl implements Sessions {
    /** The Retrofit service to perform REST calls. */
    private SessionsService service;
    /** The service client containing this operation class. */
    private SimulatorAPIImpl client;

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

    /**
     * The interface defining all the services for Sessions to be
     * used by Retrofit to perform actually REST calls.
     */
    interface SessionsService {
        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.bonsai.simulatorapi.Sessions list" })
        @GET("v2/workspaces/{workspaceName}/simulatorSessions")
        Observable<Response<ResponseBody>> list(@Path("workspaceName") String workspaceName, @Query("deployment_mode") String deploymentMode, @Query("session_status") String sessionStatus, @Query("collection") String collection, @Query("package") String packageProperty);

        @Headers({ "Content-Type: application/json-patch+json; charset=utf-8", "x-ms-logging-context: com.microsoft.bonsai.simulatorapi.Sessions create" })
        @POST("v2/workspaces/{workspaceName}/simulatorSessions")
        Observable<Response<ResponseBody>> create(@Path("workspaceName") String workspaceName, @Body SimulatorInterface body);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.bonsai.simulatorapi.Sessions get" })
        @GET("v2/workspaces/{workspaceName}/simulatorSessions/{sessionId}")
        Observable<Response<ResponseBody>> get(@Path("workspaceName") String workspaceName, @Path("sessionId") String sessionId);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.bonsai.simulatorapi.Sessions delete" })
        @HTTP(path = "v2/workspaces/{workspaceName}/simulatorSessions/{sessionId}", method = "DELETE", hasBody = true)
        Observable<Response<ResponseBody>> delete(@Path("workspaceName") String workspaceName, @Path("sessionId") String sessionId);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.bonsai.simulatorapi.Sessions getMostRecentAction" })
        @GET("v2/workspaces/{workspaceName}/simulatorSessions/{sessionId}/action")
        Observable<Response<ResponseBody>> getMostRecentAction(@Path("workspaceName") String workspaceName, @Path("sessionId") String sessionId);

        @Headers({ "Content-Type: application/json-patch+json; charset=utf-8", "x-ms-logging-context: com.microsoft.bonsai.simulatorapi.Sessions advance" })
        @POST("v2/workspaces/{workspaceName}/simulatorSessions/{sessionId}/advance")
        Observable<Response<ResponseBody>> advance(@Path("workspaceName") String workspaceName, @Path("sessionId") String sessionId, @Body SimulatorState body);

    }

    /**
     * Retrieves all of the simulators currently registered with all
     simulator gateways within this workspace.
     * The deployment_mode appears in the query string. It can be one of
     Unspecified, Testing, or Hosted. If it has a 'neq:' prefix, that means "not;"
     e.g., {.../simulatorSessions?deployment_mode=neq:Hosted} means the response should not include
     simulators that are hosted.
     The session_status can be one of Attachable, Attached, Detaching, Rejected,
     and supports the neq: prefix.
     The collection appears in the query string
     The package appears in the query string
     The filter queries can appear together, like
     {.../simulatorSessions?deployment_mode=Hosted&amp;collection=1234-455-33333}.
     *
     * @param workspaceName The workspace identifier.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ProblemDetailsException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the List&lt;SimulatorSessionSummary&gt; object if successful.
     */
    public List<SimulatorSessionSummary> list(String workspaceName) {
        return listWithServiceResponseAsync(workspaceName).toBlocking().single().body();
    }

    /**
     * Retrieves all of the simulators currently registered with all
     simulator gateways within this workspace.
     * The deployment_mode appears in the query string. It can be one of
     Unspecified, Testing, or Hosted. If it has a 'neq:' prefix, that means "not;"
     e.g., {.../simulatorSessions?deployment_mode=neq:Hosted} means the response should not include
     simulators that are hosted.
     The session_status can be one of Attachable, Attached, Detaching, Rejected,
     and supports the neq: prefix.
     The collection appears in the query string
     The package appears in the query string
     The filter queries can appear together, like
     {.../simulatorSessions?deployment_mode=Hosted&amp;collection=1234-455-33333}.
     *
     * @param workspaceName The workspace identifier.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<SimulatorSessionSummary>> listAsync(String workspaceName, final ServiceCallback<List<SimulatorSessionSummary>> serviceCallback) {
        return ServiceFuture.fromResponse(listWithServiceResponseAsync(workspaceName), serviceCallback);
    }

    /**
     * Retrieves all of the simulators currently registered with all
     simulator gateways within this workspace.
     * The deployment_mode appears in the query string. It can be one of
     Unspecified, Testing, or Hosted. If it has a 'neq:' prefix, that means "not;"
     e.g., {.../simulatorSessions?deployment_mode=neq:Hosted} means the response should not include
     simulators that are hosted.
     The session_status can be one of Attachable, Attached, Detaching, Rejected,
     and supports the neq: prefix.
     The collection appears in the query string
     The package appears in the query string
     The filter queries can appear together, like
     {.../simulatorSessions?deployment_mode=Hosted&amp;collection=1234-455-33333}.
     *
     * @param workspaceName The workspace identifier.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;SimulatorSessionSummary&gt; object
     */
    public Observable<List<SimulatorSessionSummary>> listAsync(String workspaceName) {
        return listWithServiceResponseAsync(workspaceName).map(new Func1<ServiceResponse<List<SimulatorSessionSummary>>, List<SimulatorSessionSummary>>() {
            @Override
            public List<SimulatorSessionSummary> call(ServiceResponse<List<SimulatorSessionSummary>> response) {
                return response.body();
            }
        });
    }

    /**
     * Retrieves all of the simulators currently registered with all
     simulator gateways within this workspace.
     * The deployment_mode appears in the query string. It can be one of
     Unspecified, Testing, or Hosted. If it has a 'neq:' prefix, that means "not;"
     e.g., {.../simulatorSessions?deployment_mode=neq:Hosted} means the response should not include
     simulators that are hosted.
     The session_status can be one of Attachable, Attached, Detaching, Rejected,
     and supports the neq: prefix.
     The collection appears in the query string
     The package appears in the query string
     The filter queries can appear together, like
     {.../simulatorSessions?deployment_mode=Hosted&amp;collection=1234-455-33333}.
     *
     * @param workspaceName The workspace identifier.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;SimulatorSessionSummary&gt; object
     */
    public Observable<ServiceResponse<List<SimulatorSessionSummary>>> listWithServiceResponseAsync(String workspaceName) {
        if (workspaceName == null) {
            throw new IllegalArgumentException("Parameter workspaceName is required and cannot be null.");
        }
        final String deploymentMode = null;
        final String sessionStatus = null;
        final String collection = null;
        final String packageParameter = null;
        return service.list(workspaceName, deploymentMode, sessionStatus, collection, packageParameter)
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<List<SimulatorSessionSummary>>>>() {
                @Override
                public Observable<ServiceResponse<List<SimulatorSessionSummary>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<List<SimulatorSessionSummary>> clientResponse = listDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Retrieves all of the simulators currently registered with all
     simulator gateways within this workspace.
     * The deployment_mode appears in the query string. It can be one of
     Unspecified, Testing, or Hosted. If it has a 'neq:' prefix, that means "not;"
     e.g., {.../simulatorSessions?deployment_mode=neq:Hosted} means the response should not include
     simulators that are hosted.
     The session_status can be one of Attachable, Attached, Detaching, Rejected,
     and supports the neq: prefix.
     The collection appears in the query string
     The package appears in the query string
     The filter queries can appear together, like
     {.../simulatorSessions?deployment_mode=Hosted&amp;collection=1234-455-33333}.
     *
     * @param workspaceName The workspace identifier.
     * @param deploymentMode A specifier to filter on deployment mode
     * @param sessionStatus A specifier to filter on session status
     * @param collection If present, only sessions in this collection
     * @param packageParameter If present, only sessions in this package
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ProblemDetailsException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the List&lt;SimulatorSessionSummary&gt; object if successful.
     */
    public List<SimulatorSessionSummary> list(String workspaceName, String deploymentMode, String sessionStatus, String collection, String packageParameter) {
        return listWithServiceResponseAsync(workspaceName, deploymentMode, sessionStatus, collection, packageParameter).toBlocking().single().body();
    }

    /**
     * Retrieves all of the simulators currently registered with all
     simulator gateways within this workspace.
     * The deployment_mode appears in the query string. It can be one of
     Unspecified, Testing, or Hosted. If it has a 'neq:' prefix, that means "not;"
     e.g., {.../simulatorSessions?deployment_mode=neq:Hosted} means the response should not include
     simulators that are hosted.
     The session_status can be one of Attachable, Attached, Detaching, Rejected,
     and supports the neq: prefix.
     The collection appears in the query string
     The package appears in the query string
     The filter queries can appear together, like
     {.../simulatorSessions?deployment_mode=Hosted&amp;collection=1234-455-33333}.
     *
     * @param workspaceName The workspace identifier.
     * @param deploymentMode A specifier to filter on deployment mode
     * @param sessionStatus A specifier to filter on session status
     * @param collection If present, only sessions in this collection
     * @param packageParameter If present, only sessions in this package
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<SimulatorSessionSummary>> listAsync(String workspaceName, String deploymentMode, String sessionStatus, String collection, String packageParameter, final ServiceCallback<List<SimulatorSessionSummary>> serviceCallback) {
        return ServiceFuture.fromResponse(listWithServiceResponseAsync(workspaceName, deploymentMode, sessionStatus, collection, packageParameter), serviceCallback);
    }

    /**
     * Retrieves all of the simulators currently registered with all
     simulator gateways within this workspace.
     * The deployment_mode appears in the query string. It can be one of
     Unspecified, Testing, or Hosted. If it has a 'neq:' prefix, that means "not;"
     e.g., {.../simulatorSessions?deployment_mode=neq:Hosted} means the response should not include
     simulators that are hosted.
     The session_status can be one of Attachable, Attached, Detaching, Rejected,
     and supports the neq: prefix.
     The collection appears in the query string
     The package appears in the query string
     The filter queries can appear together, like
     {.../simulatorSessions?deployment_mode=Hosted&amp;collection=1234-455-33333}.
     *
     * @param workspaceName The workspace identifier.
     * @param deploymentMode A specifier to filter on deployment mode
     * @param sessionStatus A specifier to filter on session status
     * @param collection If present, only sessions in this collection
     * @param packageParameter If present, only sessions in this package
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;SimulatorSessionSummary&gt; object
     */
    public Observable<List<SimulatorSessionSummary>> listAsync(String workspaceName, String deploymentMode, String sessionStatus, String collection, String packageParameter) {
        return listWithServiceResponseAsync(workspaceName, deploymentMode, sessionStatus, collection, packageParameter).map(new Func1<ServiceResponse<List<SimulatorSessionSummary>>, List<SimulatorSessionSummary>>() {
            @Override
            public List<SimulatorSessionSummary> call(ServiceResponse<List<SimulatorSessionSummary>> response) {
                return response.body();
            }
        });
    }

    /**
     * Retrieves all of the simulators currently registered with all
     simulator gateways within this workspace.
     * The deployment_mode appears in the query string. It can be one of
     Unspecified, Testing, or Hosted. If it has a 'neq:' prefix, that means "not;"
     e.g., {.../simulatorSessions?deployment_mode=neq:Hosted} means the response should not include
     simulators that are hosted.
     The session_status can be one of Attachable, Attached, Detaching, Rejected,
     and supports the neq: prefix.
     The collection appears in the query string
     The package appears in the query string
     The filter queries can appear together, like
     {.../simulatorSessions?deployment_mode=Hosted&amp;collection=1234-455-33333}.
     *
     * @param workspaceName The workspace identifier.
     * @param deploymentMode A specifier to filter on deployment mode
     * @param sessionStatus A specifier to filter on session status
     * @param collection If present, only sessions in this collection
     * @param packageParameter If present, only sessions in this package
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;SimulatorSessionSummary&gt; object
     */
    public Observable<ServiceResponse<List<SimulatorSessionSummary>>> listWithServiceResponseAsync(String workspaceName, String deploymentMode, String sessionStatus, String collection, String packageParameter) {
        if (workspaceName == null) {
            throw new IllegalArgumentException("Parameter workspaceName is required and cannot be null.");
        }
        return service.list(workspaceName, deploymentMode, sessionStatus, collection, packageParameter)
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<List<SimulatorSessionSummary>>>>() {
                @Override
                public Observable<ServiceResponse<List<SimulatorSessionSummary>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<List<SimulatorSessionSummary>> clientResponse = listDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Registers a simulator with the Bonsai platform.
     *
     * @param workspaceName The workspace identifier.
     * @param body Information and capabilities about the simulator.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ProblemDetailsException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the SimulatorSessionResponse object if successful.
     */
    public SimulatorSessionResponse create(String workspaceName, SimulatorInterface body) {
        return createWithServiceResponseAsync(workspaceName, body).toBlocking().single().body();
    }

    /**
     * Registers a simulator with the Bonsai platform.
     *
     * @param workspaceName The workspace identifier.
     * @param body Information and capabilities about the simulator.
     * @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<SimulatorSessionResponse> createAsync(String workspaceName, SimulatorInterface body, final ServiceCallback<SimulatorSessionResponse> serviceCallback) {
        return ServiceFuture.fromResponse(createWithServiceResponseAsync(workspaceName, body), serviceCallback);
    }

    /**
     * Registers a simulator with the Bonsai platform.
     *
     * @param workspaceName The workspace identifier.
     * @param body Information and capabilities about the simulator.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SimulatorSessionResponse object
     */
    public Observable<SimulatorSessionResponse> createAsync(String workspaceName, SimulatorInterface body) {
        return createWithServiceResponseAsync(workspaceName, body).map(new Func1<ServiceResponse<SimulatorSessionResponse>, SimulatorSessionResponse>() {
            @Override
            public SimulatorSessionResponse call(ServiceResponse<SimulatorSessionResponse> response) {
                return response.body();
            }
        });
    }

    /**
     * Registers a simulator with the Bonsai platform.
     *
     * @param workspaceName The workspace identifier.
     * @param body Information and capabilities about the simulator.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SimulatorSessionResponse object
     */
    public Observable<ServiceResponse<SimulatorSessionResponse>> createWithServiceResponseAsync(String workspaceName, SimulatorInterface body) {
        if (workspaceName == null) {
            throw new IllegalArgumentException("Parameter workspaceName is required and cannot be null.");
        }
        if (body == null) {
            throw new IllegalArgumentException("Parameter body is required and cannot be null.");
        }
        Validator.validate(body);
        return service.create(workspaceName, body)
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<SimulatorSessionResponse>>>() {
                @Override
                public Observable<ServiceResponse<SimulatorSessionResponse>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<SimulatorSessionResponse> clientResponse = createDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Retrieves a simulator session corresponding to the sessionId.
     *
     * @param workspaceName The workspace identifier.
     * @param sessionId The sessionId of the simulator session to fetch
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ProblemDetailsException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the SimulatorSessionResponse object if successful.
     */
    public SimulatorSessionResponse get(String workspaceName, String sessionId) {
        return getWithServiceResponseAsync(workspaceName, sessionId).toBlocking().single().body();
    }

    /**
     * Retrieves a simulator session corresponding to the sessionId.
     *
     * @param workspaceName The workspace identifier.
     * @param sessionId The sessionId of the simulator session to fetch
     * @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<SimulatorSessionResponse> getAsync(String workspaceName, String sessionId, final ServiceCallback<SimulatorSessionResponse> serviceCallback) {
        return ServiceFuture.fromResponse(getWithServiceResponseAsync(workspaceName, sessionId), serviceCallback);
    }

    /**
     * Retrieves a simulator session corresponding to the sessionId.
     *
     * @param workspaceName The workspace identifier.
     * @param sessionId The sessionId of the simulator session to fetch
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SimulatorSessionResponse object
     */
    public Observable<SimulatorSessionResponse> getAsync(String workspaceName, String sessionId) {
        return getWithServiceResponseAsync(workspaceName, sessionId).map(new Func1<ServiceResponse<SimulatorSessionResponse>, SimulatorSessionResponse>() {
            @Override
            public SimulatorSessionResponse call(ServiceResponse<SimulatorSessionResponse> response) {
                return response.body();
            }
        });
    }

    /**
     * Retrieves a simulator session corresponding to the sessionId.
     *
     * @param workspaceName The workspace identifier.
     * @param sessionId The sessionId of the simulator session to fetch
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SimulatorSessionResponse object
     */
    public Observable<ServiceResponse<SimulatorSessionResponse>> getWithServiceResponseAsync(String workspaceName, String sessionId) {
        if (workspaceName == null) {
            throw new IllegalArgumentException("Parameter workspaceName is required and cannot be null.");
        }
        if (sessionId == null) {
            throw new IllegalArgumentException("Parameter sessionId is required and cannot be null.");
        }
        return service.get(workspaceName, sessionId)
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<SimulatorSessionResponse>>>() {
                @Override
                public Observable<ServiceResponse<SimulatorSessionResponse>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<SimulatorSessionResponse> clientResponse = getDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Deletes the Simulator session.
     *
     * @param workspaceName The workspace identifier.
     * @param sessionId The session ID generated during registration
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ProblemDetailsException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     */
    public void delete(String workspaceName, String sessionId) {
        deleteWithServiceResponseAsync(workspaceName, sessionId).toBlocking().single().body();
    }

    /**
     * Deletes the Simulator session.
     *
     * @param workspaceName The workspace identifier.
     * @param sessionId The session ID generated during registration
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<Void> deleteAsync(String workspaceName, String sessionId, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromResponse(deleteWithServiceResponseAsync(workspaceName, sessionId), serviceCallback);
    }

    /**
     * Deletes the Simulator session.
     *
     * @param workspaceName The workspace identifier.
     * @param sessionId The session ID generated during registration
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponse} object if successful.
     */
    public Observable<Void> deleteAsync(String workspaceName, String sessionId) {
        return deleteWithServiceResponseAsync(workspaceName, sessionId).map(new Func1<ServiceResponse<Void>, Void>() {
            @Override
            public Void call(ServiceResponse<Void> response) {
                return response.body();
            }
        });
    }

    /**
     * Deletes the Simulator session.
     *
     * @param workspaceName The workspace identifier.
     * @param sessionId The session ID generated during registration
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponse} object if successful.
     */
    public Observable<ServiceResponse<Void>> deleteWithServiceResponseAsync(String workspaceName, String sessionId) {
        if (workspaceName == null) {
            throw new IllegalArgumentException("Parameter workspaceName is required and cannot be null.");
        }
        if (sessionId == null) {
            throw new IllegalArgumentException("Parameter sessionId is required and cannot be null.");
        }
        return service.delete(workspaceName, sessionId)
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Void>>>() {
                @Override
                public Observable<ServiceResponse<Void>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<Void> clientResponse = deleteDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Gets the most recent action sent to the simulator to process.
     *
     * @param workspaceName The workspace identifier.
     * @param sessionId Unique identification of the simulator.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ProblemDetailsException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the Event object if successful.
     */
    public Event getMostRecentAction(String workspaceName, String sessionId) {
        return getMostRecentActionWithServiceResponseAsync(workspaceName, sessionId).toBlocking().single().body();
    }

    /**
     * Gets the most recent action sent to the simulator to process.
     *
     * @param workspaceName The workspace identifier.
     * @param sessionId Unique identification of the simulator.
     * @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<Event> getMostRecentActionAsync(String workspaceName, String sessionId, final ServiceCallback<Event> serviceCallback) {
        return ServiceFuture.fromResponse(getMostRecentActionWithServiceResponseAsync(workspaceName, sessionId), serviceCallback);
    }

    /**
     * Gets the most recent action sent to the simulator to process.
     *
     * @param workspaceName The workspace identifier.
     * @param sessionId Unique identification of the simulator.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the Event object
     */
    public Observable<Event> getMostRecentActionAsync(String workspaceName, String sessionId) {
        return getMostRecentActionWithServiceResponseAsync(workspaceName, sessionId).map(new Func1<ServiceResponse<Event>, Event>() {
            @Override
            public Event call(ServiceResponse<Event> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets the most recent action sent to the simulator to process.
     *
     * @param workspaceName The workspace identifier.
     * @param sessionId Unique identification of the simulator.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the Event object
     */
    public Observable<ServiceResponse<Event>> getMostRecentActionWithServiceResponseAsync(String workspaceName, String sessionId) {
        if (workspaceName == null) {
            throw new IllegalArgumentException("Parameter workspaceName is required and cannot be null.");
        }
        if (sessionId == null) {
            throw new IllegalArgumentException("Parameter sessionId is required and cannot be null.");
        }
        return service.getMostRecentAction(workspaceName, sessionId)
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Event>>>() {
                @Override
                public Observable<ServiceResponse<Event>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<Event> clientResponse = getMostRecentActionDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Advance the RL agent with the new state of the simulator, and returns an action computed by our policy.
     Simulatorsession is supposed to use the returned action for stepping inside the sim and thne getting the new state.false
     You can send the same state again, as long as you didn't get a Non-Idle Action back.
     *
     * @param workspaceName The workspace identifier.
     * @param sessionId Unique identifier for the simulator.
     * @param body The new state of the simulator.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ProblemDetailsException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the Event object if successful.
     */
    public Event advance(String workspaceName, String sessionId, SimulatorState body) {
        return advanceWithServiceResponseAsync(workspaceName, sessionId, body).toBlocking().single().body();
    }

    /**
     * Advance the RL agent with the new state of the simulator, and returns an action computed by our policy.
     Simulatorsession is supposed to use the returned action for stepping inside the sim and thne getting the new state.false
     You can send the same state again, as long as you didn't get a Non-Idle Action back.
     *
     * @param workspaceName The workspace identifier.
     * @param sessionId Unique identifier for the simulator.
     * @param body The new state of the simulator.
     * @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<Event> advanceAsync(String workspaceName, String sessionId, SimulatorState body, final ServiceCallback<Event> serviceCallback) {
        return ServiceFuture.fromResponse(advanceWithServiceResponseAsync(workspaceName, sessionId, body), serviceCallback);
    }

    /**
     * Advance the RL agent with the new state of the simulator, and returns an action computed by our policy.
     Simulatorsession is supposed to use the returned action for stepping inside the sim and thne getting the new state.false
     You can send the same state again, as long as you didn't get a Non-Idle Action back.
     *
     * @param workspaceName The workspace identifier.
     * @param sessionId Unique identifier for the simulator.
     * @param body The new state of the simulator.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the Event object
     */
    public Observable<Event> advanceAsync(String workspaceName, String sessionId, SimulatorState body) {
        return advanceWithServiceResponseAsync(workspaceName, sessionId, body).map(new Func1<ServiceResponse<Event>, Event>() {
            @Override
            public Event call(ServiceResponse<Event> response) {
                return response.body();
            }
        });
    }

    /**
     * Advance the RL agent with the new state of the simulator, and returns an action computed by our policy.
     Simulatorsession is supposed to use the returned action for stepping inside the sim and thne getting the new state.false
     You can send the same state again, as long as you didn't get a Non-Idle Action back.
     *
     * @param workspaceName The workspace identifier.
     * @param sessionId Unique identifier for the simulator.
     * @param body The new state of the simulator.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the Event object
     */
    public Observable<ServiceResponse<Event>> advanceWithServiceResponseAsync(String workspaceName, String sessionId, SimulatorState body) {
        if (workspaceName == null) {
            throw new IllegalArgumentException("Parameter workspaceName is required and cannot be null.");
        }
        if (sessionId == null) {
            throw new IllegalArgumentException("Parameter sessionId is required and cannot be null.");
        }
        if (body == null) {
            throw new IllegalArgumentException("Parameter body is required and cannot be null.");
        }
        Validator.validate(body);
        return service.advance(workspaceName, sessionId, body)
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Event>>>() {
                @Override
                public Observable<ServiceResponse<Event>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<Event> clientResponse = advanceDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

}
