private void GetResponseCallBack_(TaskListener <HttpResponseMessage> listener, IAsyncResult result,
                                          HttpRequestMessage originalRequest, Logger logger, BackoffProvider backoffProvider)
        {
            if (!result.IsCompleted)
            {
                logger.Log(TraceLevel.Warn, Stage.General, StageType.RequestFailed,
                           new { message = "result is not complete.", result });
                return;
            }
            try
            {
                Task <HttpResponseMessage> resultAsTask = (Task <HttpResponseMessage>)result;
                if (resultAsTask.IsFaulted)
                {
                    if (MakeAnotherAttempt_(listener, originalRequest, logger, backoffProvider))
                    {
                        return;
                    }

                    listener.OnFail(
                        new EyesException($"HttpRequestMessage request failed: {originalRequest.Method} {originalRequest.RequestUri}",
                                          resultAsTask.Exception));
                    return;
                }
                if (resultAsTask.IsCanceled)
                {
                    if (MakeAnotherAttempt_(listener, originalRequest, logger, backoffProvider))
                    {
                        return;
                    }

                    listener.OnFail(
                        new TimeoutException($"HttpRequestMessage request timed out: {originalRequest.Method} {originalRequest.RequestUri}"));
                    return;
                }
                HttpResponseMessage response = resultAsTask.Result;
                if (response.StatusCode >= HttpStatusCode.Ambiguous)
                {
                    listener.OnFail(new EyesException($"Wrong response status: {response.StatusCode} {response.ReasonPhrase}"));
                }
                else
                {
                    listener.OnComplete(response);
                }
                response.Dispose();
            }
            catch (WebException ex)
            {
                if (MakeAnotherAttempt_(listener, originalRequest, logger, backoffProvider))
                {
                    return;
                }
                listener.OnFail(ex);
            }
        }
        private void OnComplete_(HttpResponseMessage response)
        {
            Uri location = response.Headers.Location;
            RetryConditionHeaderValue secondsToWait = response.Headers.RetryAfter;

            try
            {
                HttpStatusCode status = response.StatusCode;
                if (status == HttpStatusCode.Created)
                {
                    logger_?.Verbose("exit (CREATED)");
                    restClient_.SendAsyncRequest(listener_, location, "DELETE");
                    return;
                }

                if (status != HttpStatusCode.OK)
                {
                    listener_.OnFail(new EyesException($"Got bad status code when polling from the server. Status code: {status}"));
                    return;
                }
            }
            finally
            {
                response.Dispose();
            }

            if (location != null)
            {
                pollingUrl_ = location;
            }

            int timeToWait = sleepDuration_;

            if (secondsToWait != null)
            {
                timeToWait = (int)secondsToWait.Delta.Value.TotalMilliseconds;
            }
            else if (requestCount_++ >= 5)
            {
                sleepDuration_ *= 2;
                requestCount_   = 0;
                sleepDuration_  = Math.Min(5000, sleepDuration_);
            }

            Thread.Sleep(timeToWait);
            logger_?.Verbose("polling...");
            restClient_.SendAsyncRequest(this, pollingUrl_, "GET");
        }
        private void SendLongRequest_(TaskListener <HttpResponseMessage> listener,
                                      string path, string method, Stream body, string contentType, string accept, string contentEncoding)
        {
            Stopwatch          sw      = Stopwatch.StartNew();
            HttpRequestMessage request = null;

            try
            {
                try
                {
                    Uri requestUri = string.IsNullOrEmpty(path) ?
                                     ServerUrl : new Uri(ServerUrl, path);

                    request = CreateHttpRequestMessage(
                        requestUri, method, body, contentType, accept, contentEncoding);

                    if (request == null)
                    {
                        throw new NullReferenceException("request is null");
                    }
                    CancellationTokenSource cts         = new CancellationTokenSource(Timeout);
                    IAsyncResult            asyncResult = GetHttpClient().SendAsync(request, cts.Token).
                                                          AsApm(ar => OnLongRequestResponse_(ar, request), request, Logger);

                    if (asyncResult != null && asyncResult.CompletedSynchronously)
                    {
                        Logger.Log(TraceLevel.Notice, Stage.General,
                                   new { message = "request.BeginGetResponse completed synchronously" });
                        OnLongRequestResponse_(asyncResult, request);
                    }
                }
                catch (WebException ex)
                {
                    if (request == null || ex.Response == null)
                    {
                        throw;
                    }

                    listener.OnFail(ex);
                }
            }
            catch (Exception ex2)
            {
                if (request != null && RequestFailed != null)
                {
                    var args = new HttpRequestFailedEventArgs(sw.Elapsed, request, ex2);
                    CommonUtils.DontThrow(() => RequestFailed(this, args));
                }

                throw;
            }

            void OnLongRequestResponse_(IAsyncResult result, HttpRequestMessage originalRequest)
            {
                if (!result.IsCompleted)
                {
                    Logger.Log(TraceLevel.Notice, Stage.General, new { message = "long request not complete" });
                    return;
                }
                try
                {
                    Task <HttpResponseMessage> resultAsTask = (Task <HttpResponseMessage>)result;
                    if (resultAsTask.IsFaulted)
                    {
                        listener.OnFail(
                            new EyesException($"HttpRequestMessage request failed: {originalRequest.Method} {originalRequest.RequestUri}",
                                              resultAsTask.Exception));
                        return;
                    }
                    HttpResponseMessage response = resultAsTask.Result;
                    if (response == null)
                    {
                        throw new NullReferenceException("response is null");
                    }

                    Uri statusUrl = response.Headers.Location;
                    RequestPollingTaskListener requestPollingListener = new RequestPollingTaskListener(this, statusUrl, listener);
                    SendAsyncRequest(requestPollingListener, statusUrl, "GET");
                }
                catch (Exception ex)
                {
                    CommonUtils.LogExceptionStackTrace(Logger, Stage.General, ex);
                    listener.OnFail(ex);
                }
            }
        }