public function validate_formula($formulastr) {
        global $CFG, $DB;
        require_once($CFG->libdir.'/mathslib.php');

        $formulastr = grade_item::normalize_formula($formulastr, $this->courseid);

        if (empty($formulastr)) {
            return true;
        }

        if (strpos($formulastr, '=') !== 0) {
            return get_string('errorcalculationnoequal', 'grades');
        }

        // get used items
        if (preg_match_all('/##gi(\d+)##/', $formulastr, $matches)) {
            $useditems = array_unique($matches[1]); // remove duplicates
        } else {
            $useditems = array();
        }

        // MDL-11902
        // unset the value if formula is trying to reference to itself
        // but array keys does not match itemid
        if (!empty($this->id)) {
            $useditems = array_diff($useditems, array($this->id));
            //unset($useditems[$this->id]);
        }

        // prepare formula and init maths library
        $formula = preg_replace('/##(gi\d+)##/', '\1', $formulastr);
        $formula = new calc_formula($formula);


        if (empty($useditems)) {
            $grade_items = array();

        } else {
            list($usql, $params) = $DB->get_in_or_equal($useditems);
            $params[] = $this->courseid;
            $sql = "SELECT gi.*
                      FROM {grade_items} gi
                     WHERE gi.id $usql and gi.courseid=?"; // from the same course only!

            if (!$grade_items = $DB->get_records_sql($sql, $params)) {
                $grade_items = array();
            }
        }

        $params = array();
        foreach ($useditems as $itemid) {
            // make sure all grade items exist in this course
            if (!array_key_exists($itemid, $grade_items)) {
                return false;
            }
            // use max grade when testing formula, this should be ok in 99.9%
            // division by 0 is one of possible problems
            $params['gi'.$grade_items[$itemid]->id] = $grade_items[$itemid]->grademax;
        }

        // do the calculation
        $formula->set_params($params);
        $result = $formula->evaluate();

        // false as result indicates some problem
        if ($result === false) {
            // TODO: add more error hints
            return get_string('errorcalculationunknown', 'grades');
        } else {
            return true;
        }
    }