protected function add_attempt($userid) {
        require_capability('mod/assign:grade', $this->context);

        if ($this->get_instance()->attemptreopenmethod == ASSIGN_ATTEMPT_REOPEN_METHOD_NONE) {
            return false;
        }

        if ($this->get_instance()->teamsubmission) {
            $oldsubmission = $this->get_group_submission($userid, 0, false);
        } else {
            $oldsubmission = $this->get_user_submission($userid, false);
        }

        if (!$oldsubmission) {
            return false;
        }

        // No more than max attempts allowed.
        if ($this->get_instance()->maxattempts != ASSIGN_UNLIMITED_ATTEMPTS &&
            $oldsubmission->attemptnumber >= ($this->get_instance()->maxattempts - 1)) {
            return false;
        }

        // Create the new submission record for the group/user.
        if ($this->get_instance()->teamsubmission) {
            if (isset($this->mostrecentteamsubmission)) {
                // Team submissions can end up in this function for each user (via save_grade). We don't want to create
                // more than one attempt for the whole team.
                if ($this->mostrecentteamsubmission->attemptnumber == $oldsubmission->attemptnumber) {
                    $newsubmission = $this->get_group_submission($userid, 0, true, $oldsubmission->attemptnumber + 1);
                } else {
                    $newsubmission = $this->get_group_submission($userid, 0, false, $oldsubmission->attemptnumber);
                }
            } else {
                debugging('Please use set_most_recent_team_submission() before calling add_attempt', DEBUG_DEVELOPER);
                $newsubmission = $this->get_group_submission($userid, 0, true, $oldsubmission->attemptnumber + 1);
            }
        } else {
            $newsubmission = $this->get_user_submission($userid, true, $oldsubmission->attemptnumber + 1);
        }

        // Set the status of the new attempt to reopened.
        $newsubmission->status = ASSIGN_SUBMISSION_STATUS_REOPENED;

        // Give each submission plugin a chance to process the add_attempt.
        $plugins = $this->get_submission_plugins();
        foreach ($plugins as $plugin) {
            if ($plugin->is_enabled() && $plugin->is_visible()) {
                $plugin->add_attempt($oldsubmission, $newsubmission);
            }
        }

        $this->update_submission($newsubmission, $userid, false, $this->get_instance()->teamsubmission);
        $flags = $this->get_user_flags($userid, false);
        if (isset($flags->locked) && $flags->locked) { // May not exist.
            $this->process_unlock_submission($userid);
        }
        return true;
    }