public static IPromise <IHttpResponse> GetPromise(this HttpClient service, Uri uri, bool async, LogData trace, HttpRequest req = null)
        {
            if (req == null)
            {
                req = new HttpRequest();
            }
            req.RequestUri = uri;
            req.Method     = HttpMethod.Get;
            req.Async      = async;

#if HTTPSYNC
            if (!async && service is SyncHttpClient)
            {
                return(SendSync((SyncHttpClient)service, req, trace));
            }
#endif

            var timeout = new TimeoutSource();
            timeout.CancelAfter((int)req.Timeout.TotalMilliseconds);
            var respTask = service.SendAsync(req, HttpCompletionOption.ResponseHeadersRead, timeout.Source.Token);

            var result = respTask
                         .ContinueWith((Func <Task <HttpResponseMessage>, Task <IHttpResponse> >)HttpResponse.Create, TaskScheduler.Default)
                         .Unwrap()
                         .ToHttpPromise(timeout, trace);
            if (!async)
            {
                result.WaitNoError();
            }
            return(result);
        }
        private static IPromise <T> ToHttpPromise <T>(this Task <T> task, TimeoutSource timeout, LogData trace)
        {
            var result = new Promise <T>();

            result.CancelTarget(timeout);
            task
            .ContinueWith(t =>
            {
                if (t.IsFaulted)
                {
                    Exception ex = t.Exception;
                    while (ex != null && ex.InnerException != null && ex.GetType().Name == "AggregateException")
                    {
                        ex = ex.InnerException;
                    }

                    if (ex != null)
                    {
                        foreach (var kvp in trace)
                        {
                            ex.Data[kvp.Key] = kvp.Value;
                        }
                        trace.Add("exception", ex);
                    }
                    result.Reject(ex);
                }
                else if (t.IsCanceled)
                {
                    result.Reject(new HttpTimeoutException(string.Format("A response was not received after waiting for {0:m' minutes, 's' seconds'}", TimeSpan.FromMilliseconds(timeout.TimeoutDelay))));
                }
                else
                {
                    result.Resolve(t.Result);
                }
            });
            return(result);
        }