private async Task RunDownload(Model.Download download, Action <HttpWebRequest> configureRequest, FileRenameStreamer fileRenameStreamer)
        {
            try
            {
                _cancellationTokenSource = new CancellationTokenSource();

                var request = (HttpWebRequest)WebRequest.Create(new Uri(download.SourcePath));

                configureRequest(request);

                using (var response = await request.GetResponseAsync())
                {
                    fileRenameStreamer.SetContentLength(response.ContentLength);

                    var data = response.GetResponseStream();

                    using (fileRenameStreamer)
                    {
                        var byteBuffer = fileRenameStreamer.GetByteBuffer();
                        fileRenameStreamer.SetStreamPosition(download.GetBytesFromAllParts());
                        download.TotalFileSize = fileRenameStreamer.GetTotalFileSize();

                        await MakeDownload(download, data, byteBuffer, _cancellationTokenSource.Token, fileRenameStreamer);
                    }
                }
            }
            catch (IOException)
            {
                DownloadCancel?.Invoke(this, new MyDownloadEventArgs());
            }
            catch (OperationCanceledException)
            {
                if (download.State == CurrentDownloadState.Cancel)
                {
                    DeleteDownload(download);
                }
                else if (download.State == CurrentDownloadState.Pause)
                {
                    DownloadPause?.Invoke(this, new MyDownloadEventArgs());
                }
                else
                {
                    DeleteDownload(download);
                }
            }
            catch (WebException)
            {
                DownloadCancel?.Invoke(this, new MyDownloadEventArgs());
            }
        }
        private async Task MakeDownload(Model.Download download, Stream data, byte[] byteBuffer, CancellationToken cancellationToken, FileRenameStreamer fileRenameStreamer)
        {
            using (var output = fileRenameStreamer.GetFileStream())
            {
                var onProgressChanged = new Progress <MyProgress>(OnDownloadProgressChanged);
                var oldPercentDone    = 0.0;
                var bytesRead         = 0;

                download.StartDownloadPart();
                do
                {
                    bytesRead = await data.ReadAsync(byteBuffer, 0, byteBuffer.Length, cancellationToken);

                    download.AddBytesToPart(bytesRead);
                    fileRenameStreamer.AddCurrentBytesRead(bytesRead);

                    if (bytesRead <= 0)
                    {
                        continue;
                    }

                    await output.WriteAsync(byteBuffer, 0, bytesRead, cancellationToken);

                    oldPercentDone = SendDownloadProgress(onProgressChanged, download, oldPercentDone);
                } while (bytesRead > 0);

                download.FinishDownloadPart();
                download.DumpLogFromAllParts();

                CompleteDownload(download);
            }
        }