public async Task <bool> GetPartialSessionStream(SegmentDownloadProperties j)
        {
            Stream stream;

            try
            {
                string   partialOutput = string.Format("{0}.{1:000}", downloadPartialOutputPath, j.PartRange + 1);
                FileInfo fileinfo      = new FileInfo(partialOutput);
                                #if DEBUG
                Console.WriteLine($"\tPart {j.PartRange + 1} > Start: {j.StartRange}{(j.StartRange == 0 ? "\t" : "")}\tEnd: {j.EndRange}\tSize: {BpUtility.ToBytesCount(j.EndRange - j.StartRange)}");
                                #endif

                long existingLength = fileinfo.Exists ? fileinfo.Length : 0;

                long fileSize = (j.EndRange - j.StartRange) + 1;

                if (existingLength > fileSize)
                {
                    fileinfo.Create();
                }

                if (existingLength != fileSize)
                {
                    using (HttpClient client = new HttpClient())
                    {
                        HttpRequestMessage request = new HttpRequestMessage()
                        {
                            RequestUri = new Uri(downloadPartialInputPath)
                        };
                        request.Headers.TryAddWithoutValidation("User-Agent", App.UserAgent);
                        request.Headers.Range = new RangeHeaderValue(j.StartRange + existingLength, j.EndRange);

                        HttpResponseMessage response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, downloadPartialToken);

                        using (stream = fileinfo.Open(FileMode.Append, FileAccess.Write))
                        {
                            try
                            {
                                await ReadPartialRemoteStream(response, stream, existingLength, j.PartRange, j.EndRange - j.StartRange);
                            }
                            catch (OperationCanceledException)
                            {
                                stream.Dispose();
                                throw new OperationCanceledException();
                            }
                        }
                    }
                }
                else if (existingLength == fileSize)
                {
                    segmentDownloadProperties[j.PartRange] = new SegmentDownloadProperties(fileSize, 0, fileSize, new TimeSpan().TotalSeconds)
                    {
                        CurrentReceived = 0
                    };
                }
            }
            catch (OperationCanceledException)
            {
                                #if DEBUG
                Console.WriteLine($"Download cancelled for part {j.PartRange + 1}");
                                #endif
                return(true);
            }
            catch (Exception ex)
            {
                                #if DEBUG
                Console.WriteLine($"{ex}");
                                #endif
                return(false);
            }
            return(true);
        }
        public void DownloadFileMultipleSession(string input, string output, string customMessage = "", int threads = 1, CancellationToken token = new CancellationToken())
        {
            downloadThread            = threads;
            downloadPartialToken      = token;
            downloadPartialInputPath  = input;
            downloadPartialOutputPath = output;

            OnCompleted(new DownloadProgressCompleted()
            {
                DownloadCompleted = false
            });
            downloadPartialSize = GetContentLength(downloadPartialInputPath) ?? 0;
            long startContent, endContent;

            segmentDownloadTask       = new List <Task>();
            segmentDownloadProperties = new List <SegmentDownloadProperties>();

            List <ChunkRanges> chunkRanges = new List <ChunkRanges>();

            long partitionSize = (long)Math.Ceiling((double)downloadPartialSize / downloadThread);

            for (int i = 0; i < downloadThread; i++)
            {
                startContent = i * (downloadPartialSize / downloadThread);
                endContent   = i + 1 == downloadThread ? downloadPartialSize : ((i + 1) * (downloadPartialSize / downloadThread)) - 1;

                segmentDownloadProperties.Add(new SegmentDownloadProperties(0, 0, 0, 0)
                {
                    CurrentReceived = 0, StartRange = startContent, EndRange = endContent, PartRange = i
                });
            }

            OnResumabilityChanged(new DownloadStatusChanged(true));
                        #if DEBUG
            Console.WriteLine($"\r\nStarting Partial Download!\r\n\tTotal Size: {BpUtility.ToBytesCount(downloadPartialSize)} ({downloadPartialSize} bytes)\r\n\tThreads/Chunks: {downloadThread}");
                        #endif
            Status = ParallelHttpClientStatus.Downloading;

            try
            {
                foreach (SegmentDownloadProperties j in segmentDownloadProperties)
                {
                    segmentDownloadTask.Add(Task.Run(async() =>
                    {
                        while (!await GetPartialSessionStream(j))
                        {
                                                        #if DEBUG
                            Console.WriteLine($"Retrying to connect for chunk no: {j.PartRange + 1}...");
                                                        #endif
                            Thread.Sleep(1000);
                        }
                    }, downloadPartialToken));
                }

                Task.Run(() => GetPartialDownloadEvents());
                Task.WhenAll(segmentDownloadTask).GetAwaiter().GetResult();
            }
            catch (Exception ex)
            {
                                #if DEBUG
                Console.WriteLine($"{ex}");
                                #endif
            }

            if (!downloadPartialToken.IsCancellationRequested)
            {
                try
                {
                    MergePartialChunks();
                }
                catch (OperationCanceledException ex)
                {
                                        #if DEBUG
                    Console.WriteLine("Merging cancelled!");
                                        #endif
                    throw new OperationCanceledException("", ex);
                }
            }
            else
            {
                segmentDownloadTask.Clear();
                                #if DEBUG
                Console.WriteLine("Download cancelled!");
                                #endif
                throw new OperationCanceledException();
            }

            segmentDownloadTask.Clear();
                        #if DEBUG
            Console.WriteLine(" Done!");
                        #endif
            Status = ParallelHttpClientStatus.Idle;
        }