/// <summary>
        /// Starts the downloader Task to create chunks and download data into them, package by package.
        /// </summary>
        /// <returns></returns>
        internal Task StartDownloading()
        {
            int currentPackageIndex = 0;

            System.Console.WriteLine("Devhus.Downloader is downloading...");

            while (currentPackageIndex < TotalDownloadFilesCount)
            {
                if (State != AgentState.Busy)
                {
                    break;
                }

                System.Console.WriteLine("Devhus.Downloader checking queue permission...");
                while (QueueProceedPermission == false) /* waits for confirm to start downloading the next file */ } {
                System.Console.WriteLine("Devhus.Downloader queue permission is granted!");


                if (!DownloaderOptions.AutoQueueHandling)
                {
                    QueueProceedPermission = false;
                }

                CurrentPacakge = PackageList[currentPackageIndex] ?? null;

                if (CurrentPacakge == null || CurrentPacakge.State == PackageState.Completed)
                {
                    System.Console.WriteLine("Devhus.Downloader packge {0} was not found or was completed on download starting!", currentPackageIndex);

                    currentPackageIndex++;
                    continue;
                }


                System.Console.WriteLine("Devhus.Downloader {0} file in {1} package started", CurrentPacakge.MyFile.Name, CurrentPacakge.PackageID);

                ParentDownloder.CallDownloadFileStarted(CurrentPacakge);

                CurrentPacakge.CreateChunks();

                CurrentPacakge.StartDownload();

                currentPackageIndex++;
        }

        if (State != AgentState.Canceled)
        {
            State = AgentState.Completed;
            ParentDownloder.CallDownloadAllComplete();
        }

        return(Task.FromResult(0));
    }
        /// <summary>
        /// Resume all agent tasks safely.
        /// </summary>
        internal void Resume()
        {
            if (CurrentPacakge == null || CurrentPacakge.State != PackageState.Paused)
            {
                return;
            }

            CurrentPacakge.State  = PackageState.Downloading;
            ParentDownloder.State = DownloaderState.Resumed;

            DownloadSpeedTracker.Start();

            ParentDownloder.CallDownloadResume(CurrentPacakge);
        }
        /// <summary>
        /// Pause all agent tasks safely.
        /// </summary>
        internal void Pause()
        {
            if (CurrentPacakge == null || CurrentPacakge.State != PackageState.Downloading)
            {
                return;
            }

            CurrentPacakge.State  = PackageState.Paused;
            ParentDownloder.State = DownloaderState.Paused;

            DownloadSpeedTracker.Stop();

            ParentDownloder.CallDownloadPause();
        }
        /// <summary>
        /// Begin all agent tasks safely.
        /// </summary>
        internal async void Begin()
        {
            if (PackageList.Count == 0)
            {
                return;
            }

            System.Console.WriteLine("Devhus.Downloader is beginning...");
            State = AgentState.Busy;
            ParentDownloder.State = DownloaderState.Started;
            ParentDownloder.CallDownloadBegin();
            DownloadSpeedTracker.Start();

            await StartDownloading();
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        private void DownloadSpeedTrackerHandler(object source, ElapsedEventArgs e)
        {
            if (CurrentPacakge != null)
            {
                var progress = CurrentPacakge.Progress;

                if (CurrentPacakge.State != PackageState.Downloading || progress.SpeedBytesMs < 1)
                {
                    return;
                }

                progress.SecondsRemaining = progress.RemainingBytes / progress.SpeedBytesMs;

                ParentDownloder.CallSpeedUpdate(progress);

                progress.SpeedBytesMs = 0;
            }
        }
        /// <summary>
        /// Stops all agent tasks safely.
        /// </summary>
        internal void Stop(bool forceStop = false)
        {
            if (forceStop == false)
            {
                if (CurrentPacakge == null ||
                    (CurrentPacakge.State != PackageState.Downloading && CurrentPacakge.State != PackageState.Paused))
                {
                    return;
                }
            }

            CurrentPacakge.State  = PackageState.Canceled;
            ParentDownloder.State = DownloaderState.Stopped;
            State = AgentState.Canceled;

            DownloadSpeedTracker.Stop();

            ParentDownloder.CallDownloadStop();
        }