/// <summary>
        /// Enrolea new student to a given course. Throws NotFound, PreconditionFailed and DbException.
        /// </summary>
        /// <param name="id">The ID of the course in which the student is enroling.</param>
        /// <param name="addStudentModel">A valid StudentViewModel.</param>
        /// <returns>The updated list of students in the course.</returns>
        public List<StudentDTO> AddStudentToCourse(int id, AddStudentViewModel addStudentModel)
        {
            var course = _db.Courses.SingleOrDefault(c => c.ID == id);

            if (course == null)
                throw new NotFoundException($"No course with ID: {id}");

            var student = _db.Students.SingleOrDefault(s => s.SSN == addStudentModel.SSN);

            if (student == null)
                throw new NotFoundException($"No student with SSN: {addStudentModel.SSN}");

            if (course.MaxStudents <= GetStudentCount(course.ID))
                throw new PreconditionFailedException("Maximum number of students reached!");

            var enroled = _db.CourseEnrolments.SingleOrDefault(
                e => e.CourseID == course.ID && e.StudentID == student.ID);

            if (enroled != null && enroled.Active)
                throw new PreconditionFailedException($"{student.Name} is already enroled in {course.TemplateID}");

            var waiting = _db.CourseWaitinglists.SingleOrDefault(w => w.CourseID == id && w.StudentID == student.ID);

            if (waiting != null)
            {
                _db.CourseWaitinglists.Remove(waiting);
                _db.SaveChanges();
            }

            if (enroled != null && !enroled.Active)
            {
                enroled.Active = true;
            }
            else
            {
                _db.CourseEnrolments.Add(new CourseEnrolment
                {
                    CourseID  = course.ID,
                    StudentID = student.ID,
                    Active    = true
                });
            }

            try
            {
                _db.SaveChanges();
            }
            catch (Exception e)
            {
                throw new DbException(e);
            }

            return GetAllStudents(course.ID);
        }
        /// <summary>
        /// Add a student to a courses waiting list. Throws NotFound PreconditionFailed and DbException.
        /// </summary>
        /// <param name="id">The ID of the cours the waiting list is for.</param>
        /// <param name="addStudentModel">The view model for the student being added</param>
        /// <returns>A list of students in the courses waiting list.</returns>
        public List<StudentDTO> AddStudentToWaitingList(int id, AddStudentViewModel addStudentModel)
        {
            var course = _db.Courses.SingleOrDefault(c => c.ID == id);

            if (course == null)
                throw new NotFoundException($"No course with ID: {id}");

            var student = _db.Students.SingleOrDefault(s => s.SSN == addStudentModel.SSN);

            if (student == null)
                throw new NotFoundException($"No student with SSN: {addStudentModel.SSN}");

            var enroled =
                _db.CourseEnrolments.SingleOrDefault(ce => ce.CourseID == course.ID && ce.StudentID == student.ID && ce.Active);

            if (enroled != null)
                throw new PreconditionFailedException($"{student.Name} is enroled in the course");

            var waiting = _db.CourseWaitinglists.SingleOrDefault(e => e.CourseID == course.ID && e.StudentID == student.ID);

            if (waiting != null)
                throw new PreconditionFailedException($"{student.Name} is already on the waiting list for {course.TemplateID}");

            _db.CourseWaitinglists.Add(new CourseWaitinglist { CourseID = course.ID, StudentID = student.ID });

            try
            {
                _db.SaveChanges();
            }
            catch (Exception e)
            {
                throw new DbException(e);
            }

            return GetWaitinglist(course.ID);
        }