private void InvokeRemove(WPFDataTypes.Version v)
 {
     Task.Run(async() => {
         v.StateChangeInfo = new VersionStateChangeInfo(VersionState.Uninstalling);
         await UnregisterPackage(Path.GetFullPath(v.GameDirectory));
         Directory.Delete(v.GameDirectory, true);
         v.StateChangeInfo = null;
         if (v.UUID == WPFDataTypes.Version.UNKNOWN_UUID)
         {
             Dispatcher.Invoke(() => _versions.Remove(v));
             Debug.WriteLine("Removed imported version " + v.DisplayName);
         }
         else
         {
             v.UpdateInstallStatus();
             Debug.WriteLine("Removed release version " + v.DisplayName);
         }
     });
 }
        private void InvokeDownload(WPFDataTypes.Version v)
        {
            CancellationTokenSource cancelSource = new CancellationTokenSource();

            v.StateChangeInfo = new VersionStateChangeInfo(VersionState.Initializing);
            v.StateChangeInfo.CancelCommand = new RelayCommand((o) => cancelSource.Cancel());

            Debug.WriteLine("Download start");
            Task.Run(async() => {
                string dlPath = "Minecraft-" + v.Name + ".Appx";
                VersionDownloader downloader = _anonVersionDownloader;
                if (v.IsBeta)
                {
                    downloader = _userVersionDownloader;
                    if (Interlocked.CompareExchange(ref _userVersionDownloaderLoginTaskStarted, 1, 0) == 0)
                    {
                        _userVersionDownloaderLoginTask.Start();
                    }
                    Debug.WriteLine("Waiting for authentication");
                    try {
                        await _userVersionDownloaderLoginTask;
                        Debug.WriteLine("Authentication complete");
                    } catch (Exception e) {
                        v.StateChangeInfo = null;
                        Debug.WriteLine("Authentication failed:\n" + e.ToString());
                        MessageBox.Show("Failed to authenticate. Please make sure your account is subscribed to the beta programme.\n\n" + e.ToString(), "Authentication failed");
                        return;
                    }
                }
                try {
                    await downloader.Download(v.UUID, "1", dlPath, (current, total) => {
                        if (v.StateChangeInfo.VersionState != VersionState.Downloading)
                        {
                            Debug.WriteLine("Actual download started");
                            v.StateChangeInfo.VersionState = VersionState.Downloading;
                            if (total.HasValue)
                            {
                                v.StateChangeInfo.TotalSize = total.Value;
                            }
                        }
                        v.StateChangeInfo.DownloadedBytes = current;
                    }, cancelSource.Token);
                    Debug.WriteLine("Download complete");
                } catch (Exception e) {
                    Debug.WriteLine("Download failed:\n" + e.ToString());
                    if (!(e is TaskCanceledException))
                    {
                        MessageBox.Show("Download failed:\n" + e.ToString());
                    }
                    v.StateChangeInfo = null;
                    return;
                }
                try {
                    v.StateChangeInfo.VersionState = VersionState.Extracting;
                    string dirPath = v.GameDirectory;
                    if (Directory.Exists(dirPath))
                    {
                        Directory.Delete(dirPath, true);
                    }
                    ZipFile.ExtractToDirectory(dlPath, dirPath);
                    v.StateChangeInfo = null;
                    File.Delete(Path.Combine(dirPath, "AppxSignature.p7x"));
                    File.Delete(dlPath);
                } catch (Exception e) {
                    Debug.WriteLine("Extraction failed:\n" + e.ToString());
                    MessageBox.Show("Extraction failed:\n" + e.ToString());
                    v.StateChangeInfo = null;
                    return;
                }
                v.StateChangeInfo = null;
                v.UpdateInstallStatus();
            });
        }