public function process()
    {
        $expression = $this->getComponent();

        // Reset trail and marker arrays.
        $this->trail = array();
        $this->marker = array();

        $this->pushTrail($expression);

        while (count($this->getTrail()) > 0) {

            $expression = $this->popTrail();

            if ($this->isMarked($expression) === false && $expression instanceof Operator) {
                // This is an operator, first pass. Repush for a second pass.
                $this->mark($expression);
                $this->pushTrail($expression);
                $this->pushTrail($expression->getExpressions());
            } elseif ($this->isMarked($expression)) {
                // Operator, second pass. Process it.
                $popCount = count($expression->getExpressions());
                $operands = $this->operands->pop($popCount);
                $processor = $this->operatorProcessorFactory->createProcessor($expression, $operands);
                $processor->setState($this->getContext());
                $result = $processor->process();

                // trace the processing of the operator.
                $qtiName = $expression->getQtiClassName();
                $trace = "Operator '${qtiName}' processed.";
                $this->traceOperator($processor, $result);

                if ($expression !== $this->getComponent()) {
                    $this->operands->push($result);
                }
            } else {
                // Simple expression, process it.
                $processor = $this->expressionProcessorFactory->createProcessor($expression);
                $processor->setState($this->getContext());

                $result = $processor->process();
                $this->operands->push($result);

                // trace the processing of the expression.
                $qtiName = $expression->getQtiClassName();
                $trace = "Expression '${qtiName}' processed.";
                $this->traceExpression($processor, $result);
            }
        }

        return $result;
    }