private void ConstructOutput(VoteStorage votes, MarkerType marker, CancellationToken token) { if (votes.Count == 0) { return; } var groupByTask = GetVotesGroupedByTask(votes); bool firstTask = true; foreach (var task in groupByTask) { token.ThrowIfCancellationRequested(); if (task.Any()) { if (!firstTask) { AddLineBreak(); } firstTask = false; AddTaskLabel(task.Key); IEnumerable <CompactVote> compactTask = Enumerable.Empty <CompactVote>(); if (displayMode == DisplayMode.Compact || displayMode == DisplayMode.CompactNoVoters) { compactTask = CompactVote.GetCompactVotes(task); } switch (marker) { case MarkerType.Vote: ConstructNormalOutput(task, compactTask); break; case MarkerType.Score: ConstructScoredOutput(task, compactTask); break; case MarkerType.Approval: ConstructApprovedOutput(task, compactTask); break; case MarkerType.Rank: ConstructRankedOutput(task, compactTask); break; default: throw new ArgumentOutOfRangeException($"Unknown marker type: {marker}", nameof(marker)); } sb.AppendLine(); } } /// <summary> /// Function to wrap the logic of grouping votes by task. /// </summary> /// <param name="votes">The original vote set.</param> /// <returns>Returns the votes grouped by task.</returns> IEnumerable <VotesGroupedByTask> GetVotesGroupedByTask(VoteStorage votes) { var groupByTask = votes.GroupBy(a => a.Key.Task, StringComparer.OrdinalIgnoreCase).OrderBy(a => a.Key); groupByTask = groupByTask.OrderBy(v => voteCounter.TaskList.IndexOf(v.Key)); return(groupByTask); } }