private async Task GenerateProgressReport()
        {
            if (GeneratingProgressReport)
            {
                return;
            }

            GeneratingProgressReport = true;

            await Task.Run(() =>
            {
                // scrape Last.fm API documentation
                var apiGroup = ProgressReport.GetApiMethods();
                if (apiGroup == null)
                {
                    return;
                }

                // reflect on Last.fm assembly to find all implemented commands
                var allImplemented = Reflektor.GetImplementedCommands().Select(Reflektor.CreateCommand).Select(c => c.Method).ToList();

                // generate the markdown
                _reportPath = Path.GetFullPath(SolutionDir + ReportFilename);
                ProgressReport.WriteReport(apiGroup, allImplemented, _reportPath);

                // ui, duplicating code but w/e
                ApiProgress = (int)ProgressReport.GetPercentage(apiGroup, allImplemented);

                var notimp = new List <string>();
                foreach (var group in apiGroup)
                {
                    var implemented    = allImplemented.Where(m => m.StartsWith(group.Key.ToLowerInvariant(), StringComparison.Ordinal)).ToList();
                    var notImplemented = group.Value.Except(implemented).ToList();

                    notimp.AddRange(notImplemented);
                }

                RemainingCommands = notimp;
            });

            GeneratingProgressReport = false;
        }