public async Task CheckForUpdatesAsync()
        {
            CheckingUpdateStatus = OperationStatus.NotStarted;

            bool anyError = false;

            try {
                _checkUpdatesCancelTokenSource?.Cancel();
                _checkUpdatesCancelTokenSource = new CancellationTokenSource();

                CheckingUpdateStatus          = OperationStatus.InProgress;
                CheckingUpdatePercentComplete = 0;

#if DEBUG || VERBOSE_UPDATES
                _outputWindow.WriteLine(String.Empty);
                _outputWindow.WriteLine(Strings.CheckingForAllUpdatesStarted);
#endif

                var templatesResult = await _installedSource.GetTemplatesAsync(null, null, CancellationToken.None);

                for (int i = 0; i < templatesResult.Templates.Count; i++)
                {
                    CheckingUpdatePercentComplete = (int)((i / (double)templatesResult.Templates.Count) * 100);
                    var template = templatesResult.Templates[i];

                    _checkUpdatesCancelTokenSource.Token.ThrowIfCancellationRequested();

                    try {
#if DEBUG || VERBOSE_UPDATES
                        _outputWindow.WriteLine(Strings.CheckingTemplateUpdateStarted.FormatUI(template.Name, template.RemoteUrl));
#endif

                        var available = await _installedSource.CheckForUpdateAsync(template.RemoteUrl);

                        if (available == null)
                        {
                            _outputWindow.WriteLine(Strings.CheckingTemplateUpdateInconclusive);
#if DEBUG || VERBOSE_UPDATES
                        }
                        else if (available == true)
                        {
                            _outputWindow.WriteLine(Strings.CheckingTemplateUpdateFound);
                        }
                        else if (available == false)
                        {
                            _outputWindow.WriteLine(Strings.CheckingTemplateUpdateNotFound);
#endif
                        }

                        var installed = Installed.Templates.OfType <TemplateViewModel>().SingleOrDefault(vm => vm.RemoteUrl == template.RemoteUrl);
                        if (installed != null)
                        {
                            installed.IsUpdateAvailable = available == true;
                        }
                    } catch (Exception ex) when(!ex.IsCriticalException())
                    {
                        if (!anyError)
                        {
                            _outputWindow.ShowAndActivate();
#if DEBUG || VERBOSE_UPDATES
                            _outputWindow.WriteLine(String.Empty);
                            _outputWindow.WriteLine(Strings.CheckingForAllUpdatesStarted);
#endif
                        }

                        anyError = true;

                        _outputWindow.WriteLine(Strings.CheckingTemplateUpdateStarted.FormatUI(template.Name, template.RemoteUrl));
                        _outputWindow.WriteErrorLine(ex.Message);

                        var pex = ex as ProcessException;
                        if (pex != null)
                        {
                            _outputWindow.WriteErrorLine(string.Join(Environment.NewLine, pex.Result.StandardErrorLines ?? new string[0]));
                        }

                        _outputWindow.WriteLine(Strings.CheckingTemplateUpdateError);
                    }
                }

                CheckingUpdateStatus          = anyError ? OperationStatus.Failed : OperationStatus.Succeeded;
                CheckingUpdatePercentComplete = 100;

                if (anyError)
                {
                    _outputWindow.WriteLine(Strings.CheckingForAllUpdatesFailed);
#if DEBUG || VERBOSE_UPDATES
                }
                else
                {
                    _outputWindow.WriteLine(Strings.CheckingForAllUpdatesSuccess);
#endif
                }

                ReportEvent(CookiecutterTelemetry.TelemetryArea.Search, CookiecutterTelemetry.SearchEvents.CheckUpdate, (!anyError).ToString());
            } catch (OperationCanceledException) {
                CheckingUpdateStatus = OperationStatus.Canceled;
#if DEBUG || VERBOSE_UPDATES
                _outputWindow.WriteLine(Strings.CheckingForAllUpdatesCanceled);
#else
                if (anyError)
                {
                    _outputWindow.WriteLine(Strings.CheckingForAllUpdatesCanceled);
                }
#endif
            }
        }
        public async Task CheckForUpdatesAsync()
        {
            ResetStatus();

            try {
                _checkUpdatesCancelTokenSource?.Cancel();
                _checkUpdatesCancelTokenSource = new CancellationTokenSource();

                CheckingUpdateStatus = OperationStatus.InProgress;

                _outputWindow.WriteLine(Strings.CheckingForAllUpdatesStarted);

                bool anyError        = false;
                var  templatesResult = await _installedSource.GetTemplatesAsync(null, null, CancellationToken.None);

                foreach (var template in templatesResult.Templates)
                {
                    _checkUpdatesCancelTokenSource.Token.ThrowIfCancellationRequested();

                    try {
                        _outputWindow.WriteLine(Strings.CheckingTemplateUpdateStarted.FormatUI(template.Name, template.RemoteUrl));

                        var available = await _installedSource.CheckForUpdateAsync(template.RemoteUrl);

                        if (available.HasValue)
                        {
                            _outputWindow.WriteLine(available.Value ? Strings.CheckingTemplateUpdateFound : Strings.CheckingTemplateUpdateNotFound);
                        }
                        else
                        {
                            _outputWindow.WriteLine(Strings.CheckingTemplateUpdateInconclusive);
                        }

                        var installed = Installed.Templates.OfType <TemplateViewModel>().SingleOrDefault(vm => vm.RemoteUrl == template.RemoteUrl);
                        if (installed != null)
                        {
                            installed.IsUpdateAvailable = available == true;
                        }
                    } catch (Exception ex) when(!ex.IsCriticalException())
                    {
                        if (!anyError)
                        {
                            _outputWindow.ShowAndActivate();
                        }

                        anyError = true;

                        _outputWindow.WriteErrorLine(ex.Message);
                        _outputWindow.WriteLine(Strings.CheckingTemplateUpdateError);
                    }
                }

                CheckingUpdateStatus = anyError ? OperationStatus.Failed : OperationStatus.Succeeded;

                _outputWindow.WriteLine(anyError ? Strings.CheckingForAllUpdatesFailed : Strings.CheckingForAllUpdatesSuccess);

                ReportEvent(CookiecutterTelemetry.TelemetryArea.Search, CookiecutterTelemetry.SearchEvents.CheckUpdate, (!anyError).ToString());
            } catch (OperationCanceledException) {
                CheckingUpdateStatus = OperationStatus.Canceled;
                _outputWindow.WriteLine(Strings.CheckingForAllUpdatesCanceled);
            }
        }