/// <summary>
        /// Downloads the pages and their references, providing progress feedback
        /// </summary>
        /// <param name="progressHost">The progresshost to use for feedback</param>
        /// <returns>this</returns>
        public object Download(IProgressHost progressHost)
        {
            // Prepare the list of references to download
            progressHost.UpdateProgress(Res.Get(StringId.ProgressPreparingListOfFiles));
            foreach (PageToDownload pageToDownload in _pagesToDownload)
            {
                // Lay down a placeholder file with the correct file name
                try
                {
                    string destination = Path.Combine(_siteStorage.BasePath, pageToDownload.RelativePath);
                    destination = PathHelper.GetNonConflictingPath(destination);
                    pageToDownload.FileName = Path.GetFileName(destination);

                    using (Stream htmlStream = _siteStorage.Open(destination, AccessMode.Write)) { }
                }
                catch (Exception e)
                {
                    HandleException(e);
                }

                foreach (ReferenceToDownload reference in pageToDownload.References)
                {
                    // Don't add the same item more than once
                    if (!_referencesToDownload.ContainsKey(reference.AbsoluteUrl))
                        _referencesToDownload.Add(reference.AbsoluteUrl, reference);
                }
            }

            // Enqueue the work items
            progressHost.UpdateProgress(Res.Get(StringId.ProgressStartingDownloadOfReferences));
            IProgressHost[] progressHosts = new JointProgressHosts(progressHost, _referencesToDownload.Count, 8000, 10000).ProgressHosts;
            int tickNum = 0;
            foreach (ReferenceToDownload reference in _referencesToDownload.Values)
                workQueue.Enqueue(new DownloadWorkItem(reference, _siteStorage, progressHosts[tickNum++]));

            // Start up the parallel execution of the downloads
            ParallelExecution parallelExecution = new ParallelExecution(new ThreadStart(WorkerThreadStart), 2);
            parallelExecution.Execute();
            parallelExecution = null;

            // Now go through and get HTML for each page, and emit the HTML to disk
            ProgressTick allPagesProgress = new ProgressTick(progressHost, 2000, 10000);
            for (int i = 0; i < _pagesToDownload.Length; i++)
            {
                try
                {
                    allPagesProgress.UpdateProgress(i, _pagesToDownload.Length, string.Format(CultureInfo.CurrentCulture, Res.Get(StringId.ProgressSaving), _pagesToDownload[i].FileName));
                    WriteHtmlToDisk(_pagesToDownload[i], _siteStorage);
                }
                catch (Exception e)
                {
                    HandleException(e);
                }
                if (allPagesProgress.CancelRequested)
                    throw new OperationCancelledException();
            }

            // We're complete!
            progressHost.UpdateProgress(1, 1, Res.Get(StringId.ProgressDownloadFinished));

            return this;
        }
 public LinkedProgressTick(JointProgressHosts parent)
 {
     this.parent = parent;
 }
 public LinkedProgressTick(JointProgressHosts parent)
 {
     this.parent = parent;
 }