protected function process_assessments(array $assessments, array $diminfo, stdclass $settings) {
        global $DB;

        if (empty($assessments)) {
            return;
        }

        // reindex the passed flat structure to be indexed by assessmentid
        $assessments = $this->prepare_data_from_recordset($assessments);

        // normalize the dimension grades to the interval 0 - 100
        $assessments = $this->normalize_grades($assessments, $diminfo);

        // get a hypothetical average assessment
        $average = $this->average_assessment($assessments);

        // if unable to calculate the average assessment, set the grading grades to null
        if (is_null($average)) {
            foreach ($assessments as $asid => $assessment) {
                if (!is_null($assessment->gradinggrade)) {
                    $DB->set_field('workshop_assessments', 'gradinggrade', null, array('id' => $asid));
                }
            }
            return;
        }

        // calculate variance of dimension grades
        $variances = $this->weighted_variance($assessments);
        foreach ($variances as $dimid => $variance) {
            $diminfo[$dimid]->variance = $variance;
        }

        // for every assessment, calculate its distance from the average one
        $distances = array();
        foreach ($assessments as $asid => $assessment) {
            $distances[$asid] = $this->assessments_distance($assessment, $average, $diminfo, $settings);
        }

        // identify the best assessments - that is those with the shortest distance from the best assessment
        $bestids = array_keys($distances, min($distances));

        // for every assessment, calculate its distance from the nearest best assessment
        $distances = array();
        foreach ($bestids as $bestid) {
            $best = $assessments[$bestid];
            foreach ($assessments as $asid => $assessment) {
                $d = $this->assessments_distance($assessment, $best, $diminfo, $settings);
                if (!is_null($d) and (!isset($distances[$asid]) or $d < $distances[$asid])) {
                    $distances[$asid] = $d;
                }
            }
        }

        // calculate the grading grade
        foreach ($distances as $asid => $distance) {
            $gradinggrade = (100 - $distance);
            if ($gradinggrade < 0) {
                $gradinggrade = 0;
            }
            if ($gradinggrade > 100) {
                $gradinggrade = 100;
            }
            $grades[$asid] = grade_floatval($gradinggrade);
        }

        // if the new grading grade differs from the one stored in database, update it
        // we do not use set_field() here because we want to pass $bulk param
        foreach ($grades as $assessmentid => $grade) {
            if (grade_floats_different($grade, $assessments[$assessmentid]->gradinggrade)) {
                // the value has changed
                $record = new stdclass();
                $record->id = $assessmentid;
                $record->gradinggrade = grade_floatval($grade);
                // do not set timemodified here, it contains the timestamp of when the form was
                // saved by the peer reviewer, not when it was aggregated
                $DB->update_record('workshop_assessments', $record, true);  // bulk operations expected
            }
        }

        // done. easy, heh? ;-)
    }