public function get_correlated_tags($keepduplicates = false) {
        global $DB;

        $correlated = $DB->get_field('tag_correlation', 'correlatedtags', array('tagid' => $this->id));

        if (!$correlated) {
            return array();
        }
        $correlated = preg_split('/\s*,\s*/', trim($correlated), -1, PREG_SPLIT_NO_EMPTY);
        list($query, $params) = $DB->get_in_or_equal($correlated);

        // This is (and has to) return the same fields as the query in core_tag_tag::get_item_tags().
        $sql = "SELECT ti.id AS taginstanceid, tg.id, tg.isstandard, tg.name, tg.rawname, tg.flag,
                tg.tagcollid, ti.ordering, ti.contextid AS taginstancecontextid, ti.itemid
              FROM {tag} tg
        INNER JOIN {tag_instance} ti ON tg.id = ti.tagid
             WHERE tg.id $query AND tg.id <> ? AND tg.tagcollid = ?
          ORDER BY ti.ordering ASC, ti.id";
        $params[] = $this->id;
        $params[] = $this->tagcollid;
        $records = $DB->get_records_sql($sql, $params);
        $seen = array();
        $result = array();
        foreach ($records as $id => $record) {
            if (!$keepduplicates && !empty($seen[$record->id])) {
                continue;
            }
            $result[$id] = new static($record);
            $seen[$record->id] = true;
        }
        return $result;
    }