Version pair for game update logic
Inheritance: CrossDomainObject
        public bool DownloadUpdates(GameModel model, VersionPair versionPair)
        {
            if (model == null) {
                throw new ArgumentException("model argument cannot be null");
            }
            if (versionPair == null) {
                throw new ArgumentException("versionPair argument cannot be null");
            }
            bool updateSuccess = true;
            double downloadedContentLenght = 0;
            double WholeContentLength = 0;

            Dictionary<int, double> contentLenght = new Dictionary<int, double>();
            try {
                for (int i = versionPair.Local + 1; i <= versionPair.Remote; i++) {
                    double patchSize = GetFileLength(new Uri(string.Format(ConfigurationManager.GetConfiguration(model).PatchRemoteURL, i)));
                    WholeContentLength += patchSize;
                    contentLenght.Add(i, patchSize);
                }
            } catch (WebException) {
                return false;
            }

            for (int i = versionPair.Local + 1; i <= versionPair.Remote; i++) {
                Uri patchUri = new Uri(string.Format(ConfigurationManager.GetConfiguration(model).PatchRemoteURL, i));
                string packageFile = Path.Combine(ConfigurationManager.GetGamePath(model), string.Format("UPDATE{0}.zip", i));

                OnStatusChanged(UpdateStatusEventArgs.Stage.DOWNLOADING, i, versionPair.Remote, downloadedContentLenght, WholeContentLength, 0, 100);
                double CurrentContentLength = 0;
                if (!contentLenght.TryGetValue(i, out CurrentContentLength)) {
                    updateSuccess = false;
                    break;
                }

                int downloadAttempts = 5;
                bool patchSuccess = false;
                while (downloadAttempts > 0 && !patchSuccess) {
                    try {
                        if (File.Exists(packageFile)) {
                            File.Delete(packageFile);
                        }
                    } catch {
                        updateSuccess = false;
                        break;
                    }

                    using (WebClientEx webClient = new WebClientEx()) {
                        DownloadProgressChangedEventHandler progressChangedEventHandler = (s, e) => {
                            double dataReceived = (e.BytesReceived / (1024.0 * 1024.0));
                            double dataTotal = (e.TotalBytesToReceive / (1024.0 * 1024.0));
                            OnStatusChanged(UpdateStatusEventArgs.Stage.DOWNLOADING,
                                i, versionPair.Remote,
                                downloadedContentLenght + e.BytesReceived, WholeContentLength,
                                dataReceived, dataTotal);
                        };

                        webClient.DownloadProgressChanged += progressChangedEventHandler;
                        try {
                            webClient.DownloadFileAsync(patchUri, packageFile);
                            while (webClient.IsBusy) {
                                System.Threading.Thread.Sleep(100);
                            }
                            downloadedContentLenght += CurrentContentLength;
                        } catch {
                            downloadAttempts--;
                            continue;
                        } finally {
                            webClient.DownloadProgressChanged -= progressChangedEventHandler;
                        }
                    }
                    if (!ConfigurationManager.CheckUpdateAccess(model)) {
                        updateSuccess = false;
                        break;
                    }
                    if (ExtractUpdate(i, versionPair.Remote,
                        downloadedContentLenght, WholeContentLength,
                        packageFile, ConfigurationManager.GetGamePath(model), true)) {
                        try {
                            string versionFile = ConfigurationManager.GetLocalVersionFile(model);
                            string directory = Path.GetDirectoryName(versionFile);
                            if (!Directory.Exists(directory)) {
                                Directory.CreateDirectory(directory);
                            }
                            File.WriteAllLines(versionFile, new string[] { "[VERSION]", "version=" + i.ToString() });
                        } catch {
                            updateSuccess = false;
                            break;
                        }
                        patchSuccess = true;
                    }
                    downloadAttempts--;
                }
                if (!patchSuccess) {
                    updateSuccess = false;
                    break;
                }
            }
            return updateSuccess;
        }
 private async Task<bool> BeginUpdate(VersionPair versionPair) {
     if (!await CheckGameAccessLoop()) {
         return false;
     }
     if (!UpdateManager.DownloadUpdates(ProfileManager.CurrentProfile.GameModel, versionPair)) {
         DialogManager.ShowMessageDialog(LanguageManager.Model.ErrorOccured, LanguageManager.Model.ConnectionError);
     }
     if (!await CheckGameAccessLoop()) {
         return false;
     }
     return await ImportPackages();
 }