/// <summary>
        /// Adds the student to the course with the given ID
        /// If no course/student is found, an Object not found exception is thrown.
        /// </summary>
        /// <param name="ID"></param>
        /// <param name="student"></param>
        /// <returns></returns>
        public StudentDTO AddStudentToCourse(int ID, AddStudentToCourseViewModel student)
        {
            // 1. Validation
            var courseEntity = _db.Courses.FirstOrDefault(x => x.ID == ID);
            if(courseEntity == null)
            {
                throw new CourseNotFoundException();
            }

            var studentEntity = _db.Persons.FirstOrDefault(x => x.SSN == student.SSN);
            if (studentEntity == null)
            {
                throw new StudentNotFoundException();
            }

            // Checking to see if the course is full
            int studentCount = _db.CourseRegistrations.Count(x => x.CourseID == ID && x.Active == true);
            if (studentCount >= courseEntity.MaxStudents)
            {
                throw new CourseFullException();
            }

            // Checking to see if the student is already enrolled in the course.
            var enrolled = _db.CourseRegistrations.FirstOrDefault(x => x.StudentID == studentEntity.ID && x.CourseID == ID);
            if(enrolled != null)
            {
                if (enrolled.Active)
                {
                    throw new StudentAlreadyEnrolledException();
                }
            }

            // Checking to see if the student was on the waiting list
            // If he was, we remove him from it.
            var waiting = _db.CourseWaitingList.FirstOrDefault(x => x.StudentID == studentEntity.ID && x.CourseID == ID);
            if(waiting != null)
            {
                _db.CourseWaitingList.Remove(waiting);
                _db.SaveChanges();
            }

            // 2. Saving the registration
            // If the student was already enrolled and simply not active
            // We set his status to active.
            if(enrolled != null)
            {
                enrolled.Active = true;
            }
            else
            {
                var courseRegistration = new CourseRegistration
                {
                    CourseID = ID,
                    StudentID = studentEntity.ID,
                    Active = true
                };

                _db.CourseRegistrations.Add(courseRegistration);
                _db.SaveChanges();
            }

            // 3. Building the return object
            var studentDTO = new StudentDTO
            {
                ID = studentEntity.ID,
                Name = studentEntity.Name,
                SSN = studentEntity.SSN
            };

            return studentDTO;
        }
        /// <summary>
        /// Adds the student to the course with the given ID
        /// If no course/student is found, an Object not found exception is thrown.
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        public StudentDTO AddStudentToCourse(int ID, StudentViewModel student)
        {
            // 1. Validation
            var courseEntity = _db.Courses.FirstOrDefault(x => x.ID == ID);

            if(courseEntity == null)
            {
                throw new CourseNotFoundException();
            }

            var studentEntity = _db.Persons.FirstOrDefault(x => x.SSN == student.SSN);

            if(studentEntity == null)
            {
                throw new StudentNotFoundException();
            }

            // 2. Saving the registration
            var courseRegistration = new CourseRegistration
            {
                CourseID = ID,
                StudentID = studentEntity.ID
            };

            _db.CourseRegistrations.Add(courseRegistration);
            _db.SaveChanges();

            // 3. Building the return object
            var studentDTO = new StudentDTO
            {
                ID = studentEntity.ID,
                Name = studentEntity.Name,
                SSN = studentEntity.SSN
            };

            return studentDTO;
        }
        /// <summary>
        /// Adds the student to the waiting list
        /// of the course with the given ID
        /// </summary>
        /// <param name="ID"></param>
        /// <param name="student"></param>
        public StudentDTO AddStudentToWaitingList(int ID, AddStudentToCourseViewModel student)
        {
            // 1. Validation
            var courseEntity = _db.Courses.FirstOrDefault(x => x.ID == ID);
            if (courseEntity == null)
            {
                throw new CourseNotFoundException();
            }

            // Checking to see if the student exists
            var studentEntity = _db.Persons.FirstOrDefault(x => x.SSN == student.SSN);
            if (studentEntity == null)
            {
                throw new StudentNotFoundException();
            }

            // Checking to see if the student is already enrolled in the course.
            var enrolled = _db.CourseRegistrations.FirstOrDefault(x => x.StudentID == studentEntity.ID && x.CourseID == ID);
            if (enrolled != null)
            {
                if (enrolled.Active)
                {
                    throw new StudentAlreadyEnrolledException();
                }
            }

            // Checking to see if the student was already on the waiting list
            var waiting = _db.CourseWaitingList.FirstOrDefault(x => x.StudentID == studentEntity.ID && x.CourseID == ID);
            if (waiting != null)
            {
                throw new StudentAlreadyOnWaitingListException();
            }

            // 2. Saving the registration
            var courseRegistration = new CourseWaitingListRegistration
            {
                CourseID = ID,
                StudentID = studentEntity.ID
            };

            _db.CourseWaitingList.Add(courseRegistration);
            _db.SaveChanges();

            // 3. Building the return object
            var studentDTO = new StudentDTO
            {
                ID = studentEntity.ID,
                Name = studentEntity.Name,
                SSN = studentEntity.SSN
            };

            return studentDTO;
        }