protected static function get_course_concepts($courseid) {
        global $DB;

        if (empty($courseid)) {
            return array(array(), array());
        }

        $courseid = (int)$courseid;

        // Get info on any glossaries in this course.
        $modinfo = get_fast_modinfo($courseid);
        $cminfos = $modinfo->get_instances_of('glossary');
        if (!$cminfos) {
            // No glossaries in this course, so don't do any work.
            return array(array(), array());
        }

        $cache = \cache::make('mod_glossary', 'concepts');
        $data = $cache->get($courseid);
        if (is_array($data)) {
            list($glossaries, $allconcepts) = $data;

        } else {
            // Find all course glossaries.
            $sql = "SELECT g.id, g.name
                      FROM {glossary} g
                      JOIN {course_modules} cm ON (cm.instance = g.id)
                      JOIN {modules} m ON (m.name = 'glossary' AND m.id = cm.module)
                     WHERE g.usedynalink = 1 AND g.course = :course AND cm.visible = 1 AND m.visible = 1
                  ORDER BY g.globalglossary, g.id";
            $glossaries = $DB->get_records_sql_menu($sql, array('course' => $courseid));
            if (!$glossaries) {
                $data = array(array(), array());
                $cache->set($courseid, $data);
                return $data;
            }
            foreach ($glossaries as $id => $name) {
                $name = str_replace(':', '-', $name);
                $glossaries[$id] = replace_ampersands_not_followed_by_entity(strip_tags($name));
            }

            $allconcepts = self::fetch_concepts(array_keys($glossaries));
            foreach ($glossaries as $gid => $unused) {
                if (!isset($allconcepts[$gid])) {
                    unset($glossaries[$gid]);
                }
            }
            if (!$glossaries) {
                // This means there are no interesting concepts in the existing glossaries.
                $data = array(array(), array());
                $cache->set($courseid, $data);
                return $data;
            }
            $cache->set($courseid, array($glossaries, $allconcepts));
        }

        $concepts = $allconcepts;

        // Verify access control to glossary instances.
        foreach ($concepts as $modid => $unused) {
            if (!isset($cminfos[$modid])) {
                // This should not happen.
                unset($concepts[$modid]);
                unset($glossaries[$modid]);
                continue;
            }
            if (!$cminfos[$modid]->uservisible) {
                unset($concepts[$modid]);
                unset($glossaries[$modid]);
                continue;
            }
        }

        return array($glossaries, $concepts);
    }