'Create a closure around the system environment.
static_url - the base URL to static assets
track_function - function of (event_type, event), intended for logging
or otherwise tracking the event.
TODO: Not used, and has inconsistent args in different
files.  Update or remove.
get_module - function that takes a descriptor and returns a corresponding
module instance object.  If the current user does not have
access to that location, returns None.
render_template - a function that takes (template_file, context), and
returns rendered html.
user - The user to base the random number generator seed off of for this
request
filestore - A filestore ojbect.  Defaults to an instance of OSFS based
at settings.DATA_DIR.
xqueue - Dict containing XqueueInterface object, as well as parameters
for the specific StudentModule:
xqueue = {\'interface\': XQueueInterface object,
\'callback_url\': Callback into the LMS,
\'queue_name\': Target queuename in Xqueue}
replace_urls - TEMPORARY - A function like static_replace.replace_urls
that capa_module can use to fix up the static urls in
ajax results.
descriptor_runtime - A `DescriptorSystem` to use for loading xblocks by id
anonymous_student_id - Used for tracking modules with student id
course_id - the course_id containing this module
publish(event) - A function that allows XModules to publish events (such as grade changes)
cache - A cache object with two methods:
.get(key) returns an object from the cache or None.
.set(key, value, timeout_secs=None) stores a value in the cache with a timeout.
can_execute_unsafe_code - A function returning a boolean, whether or
not to allow the execution of unsafe, unsandboxed code.
get_python_lib_zip - A function returning a bytestring or None.  The
bytestring is the contents of a zip file that should be importable
by other Python code running in the module.
error_descriptor_class - The class to use to render XModules with errors
get_real_user - function that takes `anonymous_student_id` and returns real user_id,
associated with `anonymous_student_id`.
get_user_role - A function that returns user role. Implementation is different
for LMS and Studio.
field_data - the `FieldData` to use for backing XBlock storage.
rebind_noauth_module_to_user - rebinds module bound to AnonymousUser to a real user...used in LTI
modules, which have an anonymous handler, to set legitimate users\' data'

@contract(descriptor_runtime='DescriptorSystem')
def __init__(self, static_url, track_function, get_module, render_template, replace_urls, descriptor_runtime, user=None, filestore=None, debug=False, hostname='', xqueue=None, publish=None, node_path='', anonymous_student_id='', course_id=None, cache=None, can_execute_unsafe_code=None, replace_course_urls=None, replace_jump_to_id_urls=None, error_descriptor_class=None, get_real_user=None, field_data=None, get_user_role=None, rebind_noauth_module_to_user=None, user_location=None, get_python_lib_zip=None, **kwargs):

    kwargs.setdefault('id_reader', getattr(descriptor_runtime, 'id_reader', OpaqueKeyReader()))
    kwargs.setdefault('id_generator', getattr(descriptor_runtime, 'id_generator', AsideKeyGenerator()))
    super(ModuleSystem, self).__init__(field_data=field_data, **kwargs)
    self.STATIC_URL = static_url
    self.xqueue = xqueue
    self.track_function = track_function
    self.filestore = filestore
    self.get_module = get_module
    self.render_template = render_template
    self.DEBUG = self.debug = debug
    self.HOSTNAME = self.hostname = hostname
    self.seed = (user.id if (user is not None) else 0)
    self.replace_urls = replace_urls
    self.node_path = node_path
    self.anonymous_student_id = anonymous_student_id
    self.course_id = course_id
    self.user_is_staff = ((user is not None) and user.is_staff)
    if publish:
        self.publish = publish
    self.cache = (cache or DoNothingCache())
    self.can_execute_unsafe_code = (can_execute_unsafe_code or (lambda : False))
    self.get_python_lib_zip = (get_python_lib_zip or (lambda : None))
    self.replace_course_urls = replace_course_urls
    self.replace_jump_to_id_urls = replace_jump_to_id_urls
    self.error_descriptor_class = error_descriptor_class
    self.xmodule_instance = None
    self.get_real_user = get_real_user
    self.user_location = user_location
    self.get_user_role = get_user_role
    self.descriptor_runtime = descriptor_runtime
    self.rebind_noauth_module_to_user = rebind_noauth_module_to_user
    if user:
        self.user_id = user.id
