protected function fetch_activity_logs($activities, $starttime = false, $endtime = false) {
        global $DB;

        // Filter by context to use the db table index.
        list($contextsql, $contextparams) = $DB->get_in_or_equal(array_keys($activities), SQL_PARAMS_NAMED);
        $select = "contextid $contextsql AND timecreated > :starttime AND timecreated <= :endtime";
        $params = $contextparams + array('starttime' => $starttime, 'endtime' => $endtime);

        // Pity that we need to pass through logging readers API when most of the people just uses the standard one.
        if (!$logstore = \core_analytics\manager::get_analytics_logstore()) {
            throw new \coding_exception('No log store available');
        }
        $events = $logstore->get_events_select_iterator($select, $params, 'timecreated ASC', 0, 0);

        // Returs the logs organised by contextid, userid and eventname so it is easier to calculate activities data later.
        // At the same time we want to keep this array reasonably "not-massive".
        $processedevents = array();
        foreach ($events as $event) {
            if (!isset($processedevents[$event->contextid])) {
                $processedevents[$event->contextid] = array();
            }
            if (!isset($processedevents[$event->contextid][$event->userid])) {
                $processedevents[$event->contextid][$event->userid] = array();
            }

            // Contextid and userid have already been used to index the events, the next field to index by is eventname:
            // crud is unique per eventname, courseid is the same for all records and we append timecreated.
            if (!isset($processedevents[$event->contextid][$event->userid][$event->eventname])) {

                // Remove all data that can change between events of the same type.
                $data = (object)$event->get_data();
                unset($data->id);
                unset($data->anonymous);
                unset($data->relateduserid);
                unset($data->other);
                unset($data->origin);
                unset($data->ip);
                $processedevents[$event->contextid][$event->userid][$event->eventname] = $data;
                // We want timecreated attribute to be an array containing all user access times.
                $processedevents[$event->contextid][$event->userid][$event->eventname]->timecreated = array();
            }

            // Add the event timecreated.
            $processedevents[$event->contextid][$event->userid][$event->eventname]->timecreated[] = intval($event->timecreated);
        }
        $events->close();

        return $processedevents;
    }