public function get_questions_from_categories_and_tags_with_usage_counts($categoryids,
            qubaid_condition $qubaids, $extraconditions = '', $extraparams = array(), $tagids = array()) {
        global $DB;

        list($qcsql, $qcparams) = $DB->get_in_or_equal($categoryids, SQL_PARAMS_NAMED, 'qc');

        $select = "q.id, (SELECT COUNT(1)
                            FROM " . $qubaids->from_question_attempts('qa') . "
                           WHERE qa.questionid = q.id AND " . $qubaids->where() . "
                         ) AS previous_attempts";
        $from   = "{question} q";
        $where  = "q.category {$qcsql}
               AND q.parent = 0
               AND q.hidden = 0";
        $params = $qcparams;

        if (!empty($tagids)) {
            // We treat each additional tag as an AND condition rather than
            // an OR condition.
            //
            // For example, if the user filters by the tags "foo" and "bar" then
            // we reduce the question list to questions that are tagged with both
            // "foo" AND "bar". Any question that does not have ALL of the specified
            // tags will be omitted.
            list($tagsql, $tagparams) = $DB->get_in_or_equal($tagids, SQL_PARAMS_NAMED, 'ti');
            $tagparams['tagcount'] = count($tagids);
            $tagparams['questionitemtype'] = 'question';
            $tagparams['questioncomponent'] = 'core_question';
            $where .= " AND q.id IN (SELECT ti.itemid
                                       FROM {tag_instance} ti
                                      WHERE ti.itemtype = :questionitemtype
                                            AND ti.component = :questioncomponent
                                            AND ti.tagid {$tagsql}
                                   GROUP BY ti.itemid
                                     HAVING COUNT(itemid) = :tagcount)";
            $params += $tagparams;
        }

        if ($extraconditions) {
            $extraconditions = ' AND (' . $extraconditions . ')';
        }

        return $DB->get_records_sql_menu("SELECT $select
                                            FROM $from
                                           WHERE $where $extraconditions
                                        ORDER BY previous_attempts",
                $qubaids->from_where_params() + $params + $extraparams);
    }