'Enroll a user in a course. This saves immediately.
Returns a CoursewareEnrollment object.
`user` is a Django User object. If it hasn\'t been saved yet (no `.id`
attribute), this method will automatically save it before
adding an enrollment for it.
`course_key` is our usual course_id string (e.g. "edX/Test101/2013_Fall)
`mode` is a string specifying what kind of enrollment this is. The
default is the default course mode, \'audit\'. Other options
include \'professional\', \'verified\', \'honor\',
\'no-id-professional\' and \'credit\'.
See CourseMode in common/djangoapps/course_modes/models.py.
`check_access`: if True, we check that an accessible course actually
exists for the given course_key before we enroll the student.
The default is set to False to avoid breaking legacy code or
code with non-standard flows (ex. beta tester invitations), but
for any standard enrollment flow you probably want this to be True.
Exceptions that can be raised: NonExistentCourseError,
EnrollmentClosedError, CourseFullError, AlreadyEnrolledError.  All these
are subclasses of CourseEnrollmentException if you want to catch all of
them in the same way.
It is expected that this method is called from a method which has already
verified the user authentication.
Also emits relevant events for analytics purposes.'

@classmethod
def enroll(cls, user, course_key, mode=None, check_access=False):

    if (mode is None):
        mode = _default_course_mode(unicode(course_key))
    try:
        course = CourseOverview.get_from_id(course_key)
    except CourseOverview.DoesNotExist:
        if check_access:
            log.warning(u'User    %s    failed    to    enroll    in    non-existent    course    %s', user.username, unicode(course_key))
            raise NonExistentCourseError
    if check_access:
        if cls.is_enrollment_closed(user, course):
            log.warning(u'User    %s    failed    to    enroll    in    course    %s    because    enrollment    is    closed', user.username, course_key.to_deprecated_string())
            raise EnrollmentClosedError
        if cls.objects.is_course_full(course):
            log.warning(u'Course    %s    has    reached    its    maximum    enrollment    of    %d    learners.    User    %s    failed    to    enroll.', course_key.to_deprecated_string(), course.max_student_enrollments_allowed, user.username)
            raise CourseFullError
    if cls.is_enrolled(user, course_key):
        log.warning(u'User    %s    attempted    to    enroll    in    %s,    but    they    were    already    enrolled', user.username, course_key.to_deprecated_string())
        if check_access:
            raise AlreadyEnrolledError
    enrollment = cls.get_or_create_enrollment(user, course_key)
    enrollment.update_enrollment(is_active=True, mode=mode)
    enrollment.send_signal(EnrollStatusChange.enroll)
    return enrollment
