QPair<int, double> WorkbookParserPrivate::calculateInfix(int start, QStringList items) {
    int i = start;
    bool ok;
    qreal d, n1, n2;
    QStack<qreal> values;
    QStack<OperatorBase<qreal>*> operators;
    QPair<int, double> result;

    // TODO add in errors ie unbalanced brackets wrong number
    // of values or operators
    // TODO handle cell references and ranges.

    while(i < items.size()) {
        QString s = items.at(i);

        if (s == ")") {
            result.first = i + 1;
            result.second = values.pop();
            return result;
        }

        if (s == "(") {
            i++;
            result = calculateInfix(i, items); // Recurse.
            i = result.first;
            values.push(result.second);
            continue;
        }

        d = s.toDouble(&ok);
        if (ok) {
            values.insert(i++, d);
            continue;
        }
        // turns constants into their actual value in the list.
        ConstantBase *constant = dynamic_cast<ConstantBase*>(pPluginStore->getConstant(s));
        if (constant) {
            values.insert(i++, constant->value());
            continue;
        }

        IFunction *func = dynamic_cast<IFunction*>(pPluginStore->getFunction(s));
        if (func) {
            result = calculateInfixFunction(func, i, items); // functioss should return a value.
            i = result.first;
            values.push(result.second);
            continue;
        }

        OperatorBase<qreal> *op1 = dynamic_cast<OperatorBase<qreal>*>(pPluginStore->getOperator(s));
        if (op1) {
            if (operators.size() == 0 || operators.top()->level() < op1->level()) {
                OperatorBase<qreal> *op2 = operators.pop();
                n1 = values.pop();
                n2 = values.pop();
                d = op2->calculate(n2, n1);
                values.push(d);
            }
            operators.push(op1);

            i++;
            continue;
        }

        // TODO string handling
//        OperatorBase<QString> *ops1 = dynamic_cast<OperatorBase<QString>*>(pPluginStore->getOperator(s));
//        if (op1) {
//            // convert numbers to strings if necessary
//        }

    }

    return result;
}