'Checks whether answers to a problem are correct
Returns a map of correct/incorrect answers:
{\'success\' : \'correct\' | \'incorrect\' | AJAX alert msg string,
\'contents\' : html}'

def submit_problem(self, data, override_time=False):

    event_info = dict()
    event_info['state'] = self.lcp.get_state()
    event_info['problem_id'] = self.location.to_deprecated_string()
    self.lcp.has_saved_answers = False
    answers = self.make_dict_of_responses(data)
    answers_without_files = convert_files_to_filenames(answers)
    event_info['answers'] = answers_without_files
    metric_name = u'capa.check_problem.{}'.format
    current_time = datetime.datetime.now(utc)
    if (override_time is not False):
        current_time = override_time
    _ = self.runtime.service(self, 'i18n').ugettext
    if self.closed():
        event_info['failure'] = 'closed'
        self.track_function_unmask('problem_check_fail', event_info)
        if dog_stats_api:
            dog_stats_api.increment(metric_name('checks'), tags=[u'result:failed', u'failure:closed'])
        raise NotFoundError(_('Problem    is    closed.'))
    if (self.done and (self.rerandomize == RANDOMIZATION.ALWAYS)):
        event_info['failure'] = 'unreset'
        self.track_function_unmask('problem_check_fail', event_info)
        if dog_stats_api:
            dog_stats_api.increment(metric_name('checks'), tags=[u'result:failed', u'failure:unreset'])
        raise NotFoundError(_('Problem    must    be    reset    before    it    can    be    submitted    again.'))
    if self.lcp.is_queued():
        prev_submit_time = self.lcp.get_recentmost_queuetime()
        waittime_between_requests = self.runtime.xqueue['waittime']
        if ((current_time - prev_submit_time).total_seconds() < waittime_between_requests):
            msg = _(u'You    must    wait    at    least    {wait}    seconds    between    submissions.').format(wait=waittime_between_requests)
            return {'success': msg, 'html': ''}
    if ((self.last_submission_time is not None) and (self.submission_wait_seconds != 0)):
        seconds_since_submission = (current_time - self.last_submission_time).total_seconds()
        if (seconds_since_submission < self.submission_wait_seconds):
            remaining_secs = int((self.submission_wait_seconds - seconds_since_submission))
            msg = _(u'You    must    wait    at    least    {wait_secs}    between    submissions.    {remaining_secs}    remaining.').format(wait_secs=self.pretty_print_seconds(self.submission_wait_seconds), remaining_secs=self.pretty_print_seconds(remaining_secs))
            return {'success': msg, 'html': ''}
    try:
        correct_map = self.lcp.grade_answers(answers)
        self.attempts = (self.attempts + 1)
        self.lcp.done = True
        self.set_state_from_lcp()
        self.set_score(self.score_from_lcp())
        self.set_last_submission_time()
    except (StudentInputError, ResponseError, LoncapaProblemError) as inst:
        if self.runtime.DEBUG:
            log.warning('StudentInputError    in    capa_module:problem_check', exc_info=True)
        self.set_state_from_lcp()
        self.set_score(self.score_from_lcp())
        if self.runtime.user_is_staff:
            msg = u'Staff    debug    info:    {tb}'.format(tb=cgi.escape(traceback.format_exc()))
        else:
            escaped_message = cgi.escape(inst.args[0])
            try:
                msg = escaped_message.split('\\n')[(-2)].split(':    ', 1)[1]
            except IndexError:
                msg = escaped_message
        return {'success': msg}
    except Exception as err:
        self.set_state_from_lcp()
        self.set_score(self.score_from_lcp())
        if self.runtime.DEBUG:
            msg = u'Error    checking    problem:    {}'.format(err.message)
            msg += u'\nTraceback:\n{}'.format(traceback.format_exc())
            return {'success': msg}
        raise
    published_grade = self.publish_grade()
    success = 'correct'
    for answer_id in correct_map:
        if (not correct_map.is_correct(answer_id)):
            success = 'incorrect'
    event_info['grade'] = published_grade['grade']
    event_info['max_grade'] = published_grade['max_grade']
    event_info['correct_map'] = correct_map.get_dict()
    event_info['success'] = success
    event_info['attempts'] = self.attempts
    event_info['submission'] = self.get_submission_metadata_safe(answers_without_files, correct_map)
    self.track_function_unmask('problem_check', event_info)
    if dog_stats_api:
        dog_stats_api.increment(metric_name('checks'), tags=[u'result:success'])
        if (published_grade['max_grade'] != 0):
            dog_stats_api.histogram(metric_name('correct_pct'), (float(published_grade['grade']) / published_grade['max_grade']))
        dog_stats_api.histogram(metric_name('attempts'), self.attempts)
    html = self.get_problem_html(encapsulate=False, submit_notification=True)
    if (not self.correctness_available()):
        success = 'submitted'
    return {'success': success, 'contents': html}
