private TResponse HandleResponse <TResponse>(ClientExecutionContext context, WebResponse webResponse)
        {
            if (DeserializeResponseUseMemoryStream)
            {
                return(HandleResponseUseMemoryStream <TResponse>(context, webResponse));
            }

            ApplyWebResponseFilters(webResponse);

            TResponse response;

            using (var responseStream = webResponse.GetResponseStream())
            {
                Stopwatch deserializationWatch = new Stopwatch();
                try
                {
                    deserializationWatch.Start();
                    response         = (TResponse)context.CallFormat.StreamDeserializer(typeof(TResponse), responseStream);
                    context.Response = response;
                }
                catch (WebException ex)
                {
                    var webEx = ExceptionFactory.CreateWebException(ex);
                    throw webEx;
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                    deserializationWatch.Stop();
                    context.Metrics.DeserializationTime = deserializationWatch.ElapsedMilliseconds;
                }
            }

            if (!HandleServiceErrorManually)
            {
                CheckResponseFailure(response as IHasResponseStatus);
            }

            return(response);
        }
        private TResponse HandleResponseUseMemoryStream <TResponse>(ClientExecutionContext context, WebResponse webResponse)
        {
            ApplyWebResponseFilters(webResponse);

            TResponse response;

            using (MemoryStream ms = new MemoryStream())
            {
                string responseTypeName = typeof(TResponse).FullName;
                using (var responseStream = webResponse.GetResponseStream())
                {
                    var readStreamTransaction = new CatTransaction("SOA2Client.deserialization.readStream", responseTypeName);
                    try
                    {
                        readStreamTransaction.Start();
                        responseStream.CopyTo(ms);
                        ms.Flush();
                        ms.Seek(0, SeekOrigin.Begin);
                        readStreamTransaction.MarkSuccess();
                    }
                    catch (Exception ex)
                    {
                        readStreamTransaction.MarkFailure(ex);
                        throw;
                    }
                    finally
                    {
                        readStreamTransaction.End();
                    }
                }

                var       deserializeTransaction = new CatTransaction(CatSerializationTypes.ClientDeserializationCall, responseTypeName);
                Stopwatch deserializationWatch   = new Stopwatch();
                try
                {
                    deserializationWatch.Start();
                    deserializeTransaction.Start();
                    response = (TResponse)context.CallFormat.StreamDeserializer(typeof(TResponse), ms);
                    deserializeTransaction.MarkSuccess();
                    context.Response = response;
                }
                catch (WebException ex)
                {
                    var webEx = ExceptionFactory.CreateWebException(ex);
                    deserializeTransaction.MarkFailure(webEx);
                    throw webEx;
                }
                catch (Exception ex)
                {
                    deserializeTransaction.MarkFailure(ex);
                    throw;
                }
                finally
                {
                    deserializeTransaction.End();
                    deserializationWatch.Stop();
                    context.Metrics.DeserializationTime = deserializationWatch.ElapsedMilliseconds;
                }
            }

            if (!HandleServiceErrorManually)
            {
                CheckResponseFailure(response as IHasResponseStatus);
            }

            return(response);
        }
        protected internal WebException HandleWebException(ClientExecutionContext context, WebException webEx)
        {
            using (webEx.Response)
            {
                HttpWebResponse errorResponse = webEx.Response as HttpWebResponse;
                if (errorResponse == null)
                {
                    if (webEx is WebExceptionBase)
                    {
                        return(webEx);
                    }
                    return(ExceptionFactory.CreateWebException(webEx));
                }

                if (webEx.Status == WebExceptionStatus.ProtocolError)
                {
                    string title = string.IsNullOrWhiteSpace(errorResponse.StatusDescription) ? webEx.Message : errorResponse.StatusDescription;

                    WebProtocolException serviceEx = null;
                    if (webEx is WebProtocolException)
                    {
                        serviceEx = (WebProtocolException)webEx;
                    }
                    else
                    {
                        serviceEx = (WebProtocolException)ExceptionFactory.CreateWebException(webEx, title);
                    }

                    try
                    {
                        using (Stream stream = errorResponse.GetResponseStream())
                        {
                            if (errorResponse.ContentType.MatchesContentType(context.ContentType))
                            {
                                var bytes = stream.ReadFully();
                                using (var memoryStream = new MemoryStream(bytes))
                                {
                                    serviceEx.ResponseBody   = bytes.FromUtf8Bytes();
                                    serviceEx.ResponseObject = (GenericErrorResponseType)context.CallFormat.StreamDeserializer(typeof(GenericErrorResponseType), memoryStream);
                                }
                            }
                            else
                            {
                                serviceEx.ResponseBody = stream.ToUtf8String();
                            }
                        }
                    }
                    catch (Exception innerEx)
                    {
                        // Oh, well, we tried
                        return(new WebProtocolException(title, innerEx)
                        {
                            StatusCode = (int)errorResponse.StatusCode,
                            StatusDescription = errorResponse.StatusDescription,
                            ResponseBody = serviceEx.ResponseBody
                        });
                    }

                    //Escape deserialize exception handling and throw here
                    return(serviceEx);
                }

                return(webEx);
            }
        }