private async Task <SummaryViewModel> GenerateSummary() { List <Project> projects = await ListProjectsAsync().OnAnyThread(); Logger.Info($"Retrieved {projects.Count} projects"); if (ProjectFilter.Any() || IgnoredProjects.Any()) { if (ProjectFilter.Any()) { projects.RemoveAll(project => !ProjectFilter.Contains(project.Key)); } projects.RemoveAll(project => IgnoredProjects.Contains(project.Key)); Logger.Info($"Filtered ignored projects, {projects.Count} remaining"); } List <User> users = await ListUsersAsync().OnAnyThread(); Logger.Info($"Retrieved {users.Count} users"); if (UserFilter.Any() || IgnoredUsers.Any()) { if (UserFilter.Any()) { users.RemoveAll(user => !UserFilter.Contains(user.Key !)); } users.RemoveAll(user => IgnoredUsers.Contains(user.Key)); Logger.Info($"Filtered ignored users, {users.Count} remaining"); } if (!projects.Any() || !users.Any()) { Logger.Warn("Nothing to do"); return(new SummaryViewModel()); } Dictionary <string, UserViewModel> userDetails = new Dictionary <string, UserViewModel>(); foreach (User user in users) { userDetails.Add(user.Key, new UserViewModel(user) { OverdueIssues = await GetOverdueIssuesForUserAsync(user.Key).OnAnyThread() }); } Dictionary <string, HashSet <User> > projectUserMappings = new Dictionary <string, HashSet <User> >(); // User => project foreach (Project project in projects) { foreach (User user in await GetUsersForProjectAsync(project.Key, users).OnAnyThread()) { projectUserMappings.GetOrCreate(project.Key, () => new HashSet <User>()).Add(user); } } foreach (Project project in new List <Project>(projects)) { if (!projectUserMappings.ContainsKey(project.Key) || projectUserMappings[project.Key].Count == 0) { Logger.Warn($"Ignoring project: {project.Key}, project has no users"); projects.Remove(project); } } Dictionary <string, ProjectViewModel> projectDetails = new Dictionary <string, ProjectViewModel>(); foreach (Project project in projects) { projectDetails.Add(project.Key, new ProjectViewModel(project)); } foreach (Issue issue in await GetUnassignedIssuesForProjectAsync(projects).OnAnyThread()) { foreach (User user in projectUserMappings[issue.Project]) { userDetails[user.Key].UnassignedIssues.Add(issue); } projectDetails[issue.Project].UnassignedIssues.Add(issue); } userDetails.RemoveIf(entry => !entry.Value.OverdueIssues.Any() && !entry.Value.UnassignedIssues.Any()); projectDetails.RemoveIf(entry => !entry.Value.UnassignedIssues.Any()); return(new SummaryViewModel() { Users = userDetails.Values.ToList(), Projects = projectDetails.Values.ToList() }); }