private async Task<string> DownloadLatestPatcher()
        {
            Label = DownloadingLabel;
            try
            {
                if (CancelEvent.WaitOne(0))
                    return null;

                Downloader downloader = new Downloader(CancelEvent);
                downloader.DownloadProgress += OnDownloadProgress;

                HttpFileInfo latest = await GetLatestPatcherUrl(downloader);
                if (latest == null)
                    throw new Exception("Не удалось найти свежую версию программы установки. Проверьте файл конфигурации.");

                Maximum = latest.ContentLength;

                string filePath = Path.GetTempFileName();
                await downloader.Download(latest.Url, filePath);
                return filePath;
            }
            finally
            {
                Label = InstallLabel;
            }
        }
        protected override async Task DoAction()
        {
            Label = DownloadingLabel;
            try
            {
                if (CancelEvent.WaitOne(0))
                    return;

                Downloader downloader = new Downloader(CancelEvent);
                downloader.DownloadProgress += OnDownloadProgress;

                HttpFileInfo fileInfo = _latestTranslationInfo.Value;
                Maximum = fileInfo.ContentLength;

                await downloader.Download(fileInfo.Url, PatcherService.ArchiveFileName);

                if (fileInfo.LastModified != null)
                    File.SetLastWriteTime(PatcherService.ArchiveFileName, fileInfo.LastModified.Value);

                SubLabel = null;
            }
            finally
            {
                Label = DownloadLabel;
            }
        }
        private async Task<HttpFileInfo> GetLatestPatcherUrl(Downloader downloader)
        {
            LocalizatorEnvironmentInfo info = InteractionService.LocalizatorEnvironment.Provide();

            HttpFileInfo latest = null;
            foreach (string url in info.PatherUrls)
            {
                try
                {
                    HttpFileInfo fileInfo = await downloader.GetRemoteFileInfo(url);
                    if (latest == null || latest.LastModified < fileInfo.LastModified)
                        latest = fileInfo;
                }
                catch (Exception ex)
                {
                    Log.Warning(ex, "Не удалось получить информацию о файле: [{0}]", url);
                }
            }
            return latest;
        }
        protected override async Task DoAction()
        {
            Label = DownloadingLabel;
            try
            {
                if (CancelEvent.WaitOne(0))
                    return;

                Downloader downloader = new Downloader(CancelEvent);
                downloader.DownloadProgress += OnDownloadProgress;

                Maximum = await downloader.GetRemoteFileSize();

                await downloader.Download(PatcherService.ArchiveFileName);
            }
            finally
            {
                Label = DownloadLabel;
            }
        }
        private HttpFileInfo GetLatestTranslationInfo()
        {
            Downloader downloader = new Downloader(CancelEvent);
            LocalizatorEnvironmentInfo info = InteractionService.LocalizatorEnvironment.Provide();

            HttpFileInfo latest = null;
            foreach (string url in info.TranslationUrls)
            {
                try
                {
                    HttpFileInfo fileInfo = downloader.GetRemoteFileInfo(url).ContinueWith(t => t.Result).Result;
                    if (latest == null || latest.LastModified < fileInfo.LastModified)
                        latest = fileInfo;
                }
                catch (Exception ex)
                {
                    Log.Warning(ex, "Не удалось получить информацию о файле: [{0}]", url);
                }
            }
            
            return latest;
        }