private async Task <ApiResponse <T> > ExecAsync <T>(RestRequest req, IReadableConfiguration configuration, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
        {
            RestClient client = new RestClient(_baseUrl);

            client.ClearHandlers();
            var existingDeserializer = req.JsonSerializer as IDeserializer;

            if (existingDeserializer != null)
            {
                client.AddHandler("application/json", () => existingDeserializer);
                client.AddHandler("text/json", () => existingDeserializer);
                client.AddHandler("text/x-json", () => existingDeserializer);
                client.AddHandler("text/javascript", () => existingDeserializer);
                client.AddHandler("*+json", () => existingDeserializer);
            }
            else
            {
                var customDeserializer = new CustomJsonCodec(configuration);
                client.AddHandler("application/json", () => customDeserializer);
                client.AddHandler("text/json", () => customDeserializer);
                client.AddHandler("text/x-json", () => customDeserializer);
                client.AddHandler("text/javascript", () => customDeserializer);
                client.AddHandler("*+json", () => customDeserializer);
            }

            var xmlDeserializer = new XmlDeserializer();

            client.AddHandler("application/xml", () => xmlDeserializer);
            client.AddHandler("text/xml", () => xmlDeserializer);
            client.AddHandler("*+xml", () => xmlDeserializer);
            client.AddHandler("*", () => xmlDeserializer);

            client.Timeout = configuration.Timeout;

            if (configuration.Proxy != null)
            {
                client.Proxy = configuration.Proxy;
            }

            if (configuration.UserAgent != null)
            {
                client.UserAgent = configuration.UserAgent;
            }

            if (configuration.ClientCertificates != null)
            {
                client.ClientCertificates = configuration.ClientCertificates;
            }

            InterceptRequest(req);

            IRestResponse <T> response;

            if (RetryConfiguration.AsyncRetryPolicy != null)
            {
                var policy       = RetryConfiguration.AsyncRetryPolicy;
                var policyResult = await policy.ExecuteAndCaptureAsync(() => client.ExecuteAsync(req, cancellationToken)).ConfigureAwait(false);

                response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize <T>(policyResult.Result) : new RestResponse <T>
                {
                    Request        = req,
                    ErrorException = policyResult.FinalException
                };
            }
            else
            {
                response = await client.ExecuteAsync <T>(req, cancellationToken).ConfigureAwait(false);
            }

            // if the response type is oneOf/anyOf, call FromJSON to deserialize the data
            if (typeof(FaceRecognitionDotNet.Client.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T)))
            {
                T          instance = (T)Activator.CreateInstance(typeof(T));
                MethodInfo method   = typeof(T).GetMethod("FromJson");
                method.Invoke(instance, new object[] { response.Content });
                response.Data = instance;
            }

            InterceptResponse(req, response);

            var result = ToApiResponse(response);

            if (response.ErrorMessage != null)
            {
                result.ErrorText = response.ErrorMessage;
            }

            if (response.Cookies != null && response.Cookies.Count > 0)
            {
                if (result.Cookies == null)
                {
                    result.Cookies = new List <Cookie>();
                }
                foreach (var restResponseCookie in response.Cookies)
                {
                    var cookie = new Cookie(
                        restResponseCookie.Name,
                        restResponseCookie.Value,
                        restResponseCookie.Path,
                        restResponseCookie.Domain
                        )
                    {
                        Comment    = restResponseCookie.Comment,
                        CommentUri = restResponseCookie.CommentUri,
                        Discard    = restResponseCookie.Discard,
                        Expired    = restResponseCookie.Expired,
                        Expires    = restResponseCookie.Expires,
                        HttpOnly   = restResponseCookie.HttpOnly,
                        Port       = restResponseCookie.Port,
                        Secure     = restResponseCookie.Secure,
                        Version    = restResponseCookie.Version
                    };

                    result.Cookies.Add(cookie);
                }
            }
            return(result);
        }
        private ApiResponse <T> Exec <T>(RestRequest req, IReadableConfiguration configuration)
        {
            RestClient client = new RestClient(_baseUrl);

            client.ClearHandlers();
            var existingDeserializer = req.JsonSerializer as IDeserializer;

            if (existingDeserializer != null)
            {
                client.AddHandler("application/json", () => existingDeserializer);
                client.AddHandler("text/json", () => existingDeserializer);
                client.AddHandler("text/x-json", () => existingDeserializer);
                client.AddHandler("text/javascript", () => existingDeserializer);
                client.AddHandler("*+json", () => existingDeserializer);
            }
            else
            {
                var customDeserializer = new CustomJsonCodec(configuration);
                client.AddHandler("application/json", () => customDeserializer);
                client.AddHandler("text/json", () => customDeserializer);
                client.AddHandler("text/x-json", () => customDeserializer);
                client.AddHandler("text/javascript", () => customDeserializer);
                client.AddHandler("*+json", () => customDeserializer);
            }

            var xmlDeserializer = new XmlDeserializer();

            client.AddHandler("application/xml", () => xmlDeserializer);
            client.AddHandler("text/xml", () => xmlDeserializer);
            client.AddHandler("*+xml", () => xmlDeserializer);
            client.AddHandler("*", () => xmlDeserializer);

            client.Timeout = configuration.Timeout;

            if (configuration.Proxy != null)
            {
                client.Proxy = configuration.Proxy;
            }

            if (configuration.UserAgent != null)
            {
                client.UserAgent = configuration.UserAgent;
            }

            if (configuration.ClientCertificates != null)
            {
                client.ClientCertificates = configuration.ClientCertificates;
            }

            InterceptRequest(req);

            IRestResponse <T> response;

            if (RetryConfiguration.RetryPolicy != null)
            {
                var policy       = RetryConfiguration.RetryPolicy;
                var policyResult = policy.ExecuteAndCapture(() => client.Execute(req));
                response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize <T>(policyResult.Result) : new RestResponse <T>
                {
                    Request        = req,
                    ErrorException = policyResult.FinalException
                };
            }
            else
            {
                response = client.Execute <T>(req);
            }

            InterceptResponse(req, response);

            var result = ToApiResponse(response);

            if (response.ErrorMessage != null)
            {
                result.ErrorText = response.ErrorMessage;
            }

            if (response.Cookies != null && response.Cookies.Count > 0)
            {
                if (result.Cookies == null)
                {
                    result.Cookies = new List <Cookie>();
                }
                foreach (var restResponseCookie in response.Cookies)
                {
                    var cookie = new Cookie(
                        restResponseCookie.Name,
                        restResponseCookie.Value,
                        restResponseCookie.Path,
                        restResponseCookie.Domain
                        )
                    {
                        Comment    = restResponseCookie.Comment,
                        CommentUri = restResponseCookie.CommentUri,
                        Discard    = restResponseCookie.Discard,
                        Expired    = restResponseCookie.Expired,
                        Expires    = restResponseCookie.Expires,
                        HttpOnly   = restResponseCookie.HttpOnly,
                        Port       = restResponseCookie.Port,
                        Secure     = restResponseCookie.Secure,
                        Version    = restResponseCookie.Version
                    };

                    result.Cookies.Add(cookie);
                }
            }
            return(result);
        }