protected static function get_global_concepts() {
        global $DB;

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

        } else {
            // Find all global glossaries - no access control here.
            $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.globalglossary = 1 AND cm.visible = 1 AND m.visible = 1
                  ORDER BY g.globalglossary, g.id";
            $glossaries = $DB->get_records_sql_menu($sql);
            if (!$glossaries) {
                $data = array(array(), array());
                $cache->set(0, $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]);
                }
            }
            $cache->set(0, array($glossaries, $allconcepts));
        }

        // NOTE: no access control is here because it would be way too expensive to check access
        //       to all courses that contain the global glossaries.
        return array($glossaries, $allconcepts);
    }