/// <summary>
        /// Returns an assignment group result, for a given user and assignment group.
        /// </summary>
        public AssignmentGroupResult GetAssignmentGroupResult(
            string assignmentGroupName,
            IList <Assignment> assignments,
            Section section,
            User user,
            IList <UserQuestionSubmission> submissions,
            bool admin)
        {
            var sectionAssignmentsInGroup = _assignmentFilter.FilterAssignments
                                            (
                assignments,
                section,
                assignmentGroupName
                                            );

            var assignmentGroupSubmissionsForUser = _assignmentFilter.FilterSubmissions
                                                    (
                sectionAssignmentsInGroup,
                submissions,
                user
                                                    );

            var assignmentResults = sectionAssignmentsInGroup.Select
                                    (
                assignment => _assignmentResultGenerator.CreateAssignmentResult
                (
                    section,
                    assignment,
                    user,
                    admin,
                    assignmentGroupSubmissionsForUser
                )
                                    ).ToList();

            return(new AssignmentGroupResult
                   (
                       assignmentGroupName,
                       user.LastName,
                       user.FirstName,
                       _assignmentGroupScoreCalculator.GetAssignmentGroupScore
                       (
                           assignmentResults,
                           roundDigits: 1
                       ),
                       _assignmentGroupScoreCalculator.GetAssignmentGroupTotalPoints
                       (
                           sectionAssignmentsInGroup,
                           roundDigits: 1
                       ),
                       assignmentResults,
                       _assignmentGroupScoreCalculator.GetAssignmentGroupStatus
                       (
                           assignmentResults
                       )
                   ));
        }
        /// <summary>
        /// Calculates the score for a single assignment group in a single section,
        /// for all students.
        /// </summary>
        public SectionAssignmentResults GetSectionAssignmentGroupResults(
            string assignmentGroupName,
            IList <Assignment> assignments,
            Section section,
            IList <User> users,
            IList <UserQuestionSubmission> submissions)
        {
            var sectionAssignmentsInGroup = _assignmentFilter.FilterAssignments
                                            (
                assignments,
                section,
                assignmentGroupName
                                            );

            var assignmentGroupSubmissions = _assignmentFilter.FilterSubmissions
                                             (
                sectionAssignmentsInGroup,
                submissions
                                             );

            var assignmentGroupSubmissionsByUser = assignmentGroupSubmissions
                                                   .GroupBy(s => s.UserQuestionData.UserId)
                                                   .ToDictionary(g => g.Key, g => g.ToList());

            var studentResults = users
                                 .OrderBy(u => u.LastName)
                                 .ThenBy(u => u.FirstName)
                                 .Select
                                 (
                user => _assignmentGroupResultGenerator.GetAssignmentGroupResult
                (
                    assignmentGroupName,
                    sectionAssignmentsInGroup,
                    section,
                    user,
                    assignmentGroupSubmissionsByUser.GetValueOrNew(user.Id),
                    admin: true
                )
                                 ).ToList();

            return(new SectionAssignmentResults
                   (
                       assignmentGroupName,
                       section.DisplayName,
                       _assignmentGroupScoreCalculator.GetAssignmentGroupTotalPoints
                       (
                           sectionAssignmentsInGroup,
                           roundDigits: 1
                       ),
                       studentResults
                   ));
        }
        /// <summary>
        /// Returns the assignment results for the given set of submissions.
        /// </summary>
        public IList <SectionAssignmentResults> GetAssignmentGroupResultsSnapshot(
            IList <Assignment> assignments,
            IList <User> users,
            Section section,
            IList <UserQuestionSubmission> submissions,
            DateTime snapshotDate)
        {
            var sectionAssignments = _assignmentFilter.FilterAssignments
                                     (
                assignments,
                section,
                assignmentGroupName: null,
                maxDueDate: snapshotDate
                                     );

            var assignmentGroups = _assignmentFilter.GetAssignmentGroups
                                   (
                section,
                sectionAssignments
                                   );

            var sectionAssignmentSubmissions = _assignmentFilter.FilterSubmissions
                                               (
                sectionAssignments,
                submissions,
                null /*user*/,
                snapshotDate
                                               );

            var submissionsByGroup = sectionAssignmentSubmissions.GroupBy
                                     (
                submission => submission.UserQuestionData
                .AssignmentQuestion
                .Assignment
                .GroupName
                                     ).ToDictionary(g => g.Key, g => g.ToList());

            return(assignmentGroups.Select
                   (
                       assignmentGroup => _sectionAssignmentReportGenerator
                       .GetSectionAssignmentGroupResults
                       (
                           assignmentGroup.Key,
                           assignmentGroup.ToList(),
                           section,
                           users,
                           submissionsByGroup.GetValueOrNew(assignmentGroup.Key)
                       )
                   ).ToList());
        }
        /// <summary>
        /// Calculates the scores of all assignment groups for a given student.
        /// </summary>
        public StudentAssignmentResults GetStudentAssignmentGroupResults(
            User user,
            Section section,
            IList <Assignment> assignments,
            IList <UserQuestionSubmission> submissions,
            bool admin)
        {
            var sectionAssignments = _assignmentFilter.FilterAssignments
                                     (
                assignments,
                section
                                     );

            var userSubmissions = _assignmentFilter.FilterSubmissions
                                  (
                sectionAssignments,
                submissions,
                user
                                  );

            var assignmentGroups = _assignmentFilter.GetAssignmentGroups
                                   (
                section,
                sectionAssignments
                                   );

            var assignmentGroupResults = assignmentGroups.Select
                                         (
                assignmentGroup => _assignmentGroupResultGenerator.GetAssignmentGroupResult
                (
                    assignmentGroup.Key,
                    assignmentGroup.ToList(),
                    section,
                    user,
                    userSubmissions,
                    admin
                )
                                         ).ToList();

            return(new StudentAssignmentResults
                   (
                       user.LastName,
                       user.FirstName,
                       section?.DisplayName,
                       assignmentGroupResults
                   ));
        }