private void OnRequestStreamReady(Stream requestStream)
        {
            this.requestStream = requestStream;
            Debug.Assert(this.requestStream != null);

            var copyOperation = new StreamCopyOperation(
                this.LiveClient,
                ApiMethod.Upload,
                this.InputStream,
                this.requestStream,
                this.totalBytesToSend,
                this.progress,
                this.Dispatcher,
                (isCancelled, error) =>
            {
                if (isCancelled)
                {
                    this.Cancel();
                }

                this.OnCopyCompleted(error);
            });

            Platform.RegisterForCancel(null, copyOperation.Cancel);

            copyOperation.Execute();
        }
        protected override void OnWebResponseReceived(WebResponse response)
        {
            // We are done with the HttpWebRequest so let's remove our reference to it.
            // If we hold on to it and Cancel is called, our parent class, WebOperation, will call this.Request.Abort
            // and this causes a Deadlock in the stream.BeginRead call in StreamCopyOperation. Not fun.
            this.Request = null;

            HttpStatusCode status = ((HttpWebResponse)response).StatusCode;

            if (status != HttpStatusCode.OK)
            {
                var result = this.CreateOperationResultFrom(response);
                if (result.Error is FormatException)
                {
                    // We do expect non-JSON errors from other data providers for download requests.
                    // If we can't understand the response body, we'll just return a generic error message.
                    var error = new LiveConnectException(
                        ApiOperation.ApiServerErrorCode,
                        string.Format(
                            CultureInfo.CurrentUICulture,
                            ResourceHelper.GetString("ServerErrorWithStatus"),
                            status.ToString()));

                    result = new LiveOperationResult(error, false);
                }

                this.CompleteOperation(result.Error);
            }
            else if (((HttpWebResponse)response).StatusCode != HttpStatusCode.OK)
            {
                var result = this.CreateOperationResultFrom(response);
                this.CompleteOperation(result.Error);
            }
            else
            {
                this.response = response;
                Stream responseStream = this.response.GetResponseStream();
                this.outputStream = new MemoryStream();
                long   totalBytesToReceive;
                string contentLength = response.Headers[DownloadOperation.HttpHeaderContentLength];
                if (!string.IsNullOrEmpty(contentLength))
                {
                    if (!long.TryParse(contentLength, out totalBytesToReceive))
                    {
                        totalBytesToReceive = DownloadOperation.UnknownFileSize;
                    }
                }
                else
                {
                    totalBytesToReceive = DownloadOperation.UnknownFileSize;
                }

                this.streamCopyOperation = new StreamCopyOperation(
                    this.LiveClient,
                    ApiMethod.Download,
                    responseStream,
                    this.outputStream,
                    totalBytesToReceive,
                    this.progress,
                    this.Dispatcher,
                    (isCancelled, error) =>
                {
                    if (isCancelled)
                    {
                        this.Cancel();
                    }

                    this.CompleteOperation(error);
                });

                Platform.RegisterForCancel(null, this.streamCopyOperation.Cancel);

                this.streamCopyOperation.Execute();
            }
        }