public function apply_completion($data, $updateinstances) {
        $updated = false;
        $needreset = [];
        $modinfo = get_fast_modinfo($this->courseid);

        $cmids = $data->cmid;

        $data = (array)$data;
        unset($data['id']); // This is a course id, we don't want to confuse it with cmid or instance id.
        unset($data['cmid']);
        unset($data['submitbutton']);

        foreach ($cmids as $cmid) {
            $cm = $modinfo->get_cm($cmid);
            if (self::can_edit_bulk_completion($this->courseid, $cm) && $this->apply_completion_cm($cm, $data, $updateinstances)) {
                $updated = true;
                if ($cm->completion != COMPLETION_TRACKING_MANUAL || $data['completion'] != COMPLETION_TRACKING_MANUAL) {
                    // If completion was changed we will need to reset it's state. Exception is when completion was and remains as manual.
                    $needreset[] = $cm->id;
                }
            }
            // Update completion calendar events.
            $completionexpected = ($data['completionexpected']) ? $data['completionexpected'] : null;
            \core_completion\api::update_completion_date_event($cm->id, $cm->modname, $cm->instance, $completionexpected);
        }
        if ($updated) {
            // Now that modules are fully updated, also update completion data if required.
            // This will wipe all user completion data and recalculate it.
            rebuild_course_cache($this->courseid, true);
            $modinfo = get_fast_modinfo($this->courseid);
            $completion = new \completion_info($modinfo->get_course());
            foreach ($needreset as $cmid) {
                $completion->reset_all_state($modinfo->get_cm($cmid));
            }

            // And notify the user of the result.
            \core\notification::add(get_string('activitycompletionupdated', 'core_completion'), \core\notification::SUCCESS);
        }
    }