public async Task<Stream> PostAsync(RestHost host, string url, string data, Action<HttpWebRequest> adjustRequest)
        {
            bool retry = true;
            HttpWebRequest request = null;
            ExceptionDispatchInfo capturedException = null;
            while (retry)
            {
                retry = false;

                try
                {
                    byte[] bytes = null;

                    request = BuildStandardPostRequest(host, url, data, null, adjustRequest, out bytes);
                    using (var requestStream = await request.GetRequestStreamAsync())
                    {
                        await requestStream.WriteAsync(bytes, 0, bytes.Length);
                        requestStream.Close();
                    }

                    var response = (HttpWebResponse)request.GetResponse();
                    return response.GetResponseStream();
                }
                catch (WebException ex)
                {
                    capturedException = ExceptionDispatchInfo.Capture(ex);
                }

                if (capturedException != null)
                {
                    var webException = capturedException.SourceException as WebException;
                    if (webException != null)
                    {
                        var errorResponse = webException.Response as HttpWebResponse;
                        if (errorResponse != null && errorResponse.StatusCode == HttpStatusCode.Forbidden && host.RetryFailedRemoteRequest(request))
                            retry = true;
                        else if (errorResponse != null && errorResponse.StatusCode == HttpStatusCode.InternalServerError)
                            return errorResponse.GetResponseStream();
                        else
                            capturedException.Throw();
                    }
                    else
                    {
                        capturedException.Throw();
                    }

                }
            }

            return null;
        }
        public Stream Get(RestHost host, string url, Action<HttpWebRequest> adjustRequest)
        {
            bool retry = true;
            HttpWebRequest request = null;
            ExceptionDispatchInfo capturedException = null;
            while (retry)
            {
                retry = false;

                try
                {
                    request = BuildGetRequest(host, url, adjustRequest);
                    var response = (HttpWebResponse)request.GetResponse();
                    Stream stream = null;

                    var str = response.GetResponseStream();
                    return str;
                }
                catch (WebException ex)
                {
                    var errorResponse = ex.Response as HttpWebResponse;
                    if (errorResponse != null && errorResponse.StatusCode == HttpStatusCode.Forbidden && host.RetryFailedRemoteRequest(request))
                        retry = true;
                    else if (errorResponse != null && errorResponse.StatusCode == HttpStatusCode.InternalServerError)
                        return errorResponse.GetResponseStream();
                    else
                        throw ex;
                }
            }

            return null;
        }
        public async Task<Stream> PostEndpointStream(RestHost host, string url, Stream postStream, Action<HttpWebRequest> adjustRequest, Action<WebResponse> responseAction)
        {
            bool retry = true;
            HttpWebRequest request = null;
            ExceptionDispatchInfo capturedException = null;
            while (retry)
            {
                retry = false;
                try
                {
                    request = CreateRequest(host, url, adjustRequest, host.PostTimeout);
                    request.Method = "POST";
                    request.ContentType = "application/octet-stream";

                    if (postStream == null)
                    {
                        request.ContentLength = 0;
                    }
                    else
                    {
                        request.ContentLength = postStream.Length;
                        using (var requestStream = await request.GetRequestStreamAsync())
                        {
                            byte[] buffer = new byte[64 * 1024];
                            int read;
                            while ((read = await postStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                            {
                                await requestStream.WriteAsync(buffer, 0, read);
                            }
                            requestStream.Close();
                        }
                    }

                    var response = await request.GetResponseAsync();
                    if (responseAction != null)
                        responseAction(response);

                    return response.GetResponseStream();
                }
                catch (WebException ex)
                {
                    capturedException = ExceptionDispatchInfo.Capture(ex);
                }

                if (capturedException != null)
                {
                    var webException = capturedException.SourceException as WebException;
                    if (webException != null)
                    {
                        var errorResponse = webException.Response as HttpWebResponse;
                        if (errorResponse != null && errorResponse.StatusCode == HttpStatusCode.Forbidden &&
                            host.RetryFailedRemoteRequest(request))
                            retry = true;
                        else
                            capturedException.Throw();
                    }
                    else
                    {
                        capturedException.Throw();
                    }

                }
            }

            return null;
        }
        public async Task<Stream> GetAsync(RestHost host, string url, Action<HttpWebRequest> adjustRequest)
        {
            bool retry = true;
            HttpWebRequest request = null;
            ExceptionDispatchInfo capturedException = null;
            while (retry)
            {
                retry = false;

                try
                {
                    request = BuildGetRequest(host, url, adjustRequest);

                    var response = await request.GetResponseAsync();
                    return ((HttpWebResponse)response).GetResponseStream();
                }
                catch (WebException ex)
                {
                    capturedException = ExceptionDispatchInfo.Capture(ex);
                }
            }

            if (capturedException != null)
            {
                var webException = capturedException.SourceException as WebException;
                if (webException != null)
                {
                    var errorResponse = webException.Response as HttpWebResponse;
                    if (errorResponse != null && errorResponse.StatusCode == HttpStatusCode.Forbidden && host.RetryFailedRemoteRequest(request))
                        retry = true;
                    else if (errorResponse != null && errorResponse.StatusCode == HttpStatusCode.InternalServerError)
                        return errorResponse.GetResponseStream();
                    else
                        capturedException.Throw();
                }
                else
                {
                    capturedException.Throw();
                }

            }
            return null;
        }
        public Stream Post(RestHost host, string url, string data, Action<HttpWebRequest> adjustRequest)
        {
            bool retry = true;
            HttpWebRequest request = null;
            while (retry)
            {
                retry = false;

                try
                {
                    byte[] bytes = null;

                    request = BuildStandardPostRequest(host, url, data, null, adjustRequest, out bytes);
                    using (var requestStream = request.GetRequestStream())
                    {
                        requestStream.Write(bytes, 0, bytes.Length);
                        requestStream.Close();
                    }
                    var response = (HttpWebResponse)request.GetResponse();
                    return response.GetResponseStream();

                }
                catch (WebException ex)
                {
                    var errorResponse = ex.Response as HttpWebResponse;
                    if (errorResponse != null && errorResponse.StatusCode == HttpStatusCode.Forbidden && host.RetryFailedRemoteRequest(request))
                        retry = true;
                    else if (errorResponse != null && errorResponse.StatusCode == HttpStatusCode.InternalServerError)
                        return errorResponse.GetResponseStream();
                    else
                        throw ex;
                }

            }

            return null;
        }