/**
  * Evaluates a dynamic expression. Acts both as a factory as well as an
  * abstraction component to evaluate expressions.
  *
  * @param DomNode $dataNode The APF DOM node that can be used to retrieve the model information.
  * @param string $expressionString The APF dynamic expression string.
  *
  * @return string The result of the expression evaluation.
  * @throws Exception In case evaluation of the given expression fails.
  *
  * @author Christian Achatz
  * @version
  * Version 0.1, 29.01.2014<br />
  */
 public static function evaluate(DomNode &$dataNode, $expressionString)
 {
     $parts = explode('->', $expressionString);
     try {
         // always evaluate the first part separately (even if we have array access expressions later on)
         $expression = new ModelEvaluationExpression($parts[0], $dataNode);
         $result = $expression->getResult();
         foreach ($parts as $part) {
             $openingNormalBracket = strpos($part, MethodEvaluationExpression::BRACKET_OPEN);
             if ($openingNormalBracket !== false) {
                 $expression = new MethodEvaluationExpression($part, $result);
                 $result = $expression->getResult();
             } else {
                 $openingSquareBracket = strpos($part, ArrayAccessEvaluationExpression::BRACKET_OPEN);
                 if ($openingSquareBracket !== false) {
                     $expression = new ArrayAccessEvaluationExpression($part, $result);
                     $result = $expression->getResult();
                 }
             }
         }
     } catch (Exception $e) {
         // re-throw with more content
         throw new ParserException('Execution of expression "' . $expressionString . '" failed with message "' . $e->getMessage() . '"', E_USER_ERROR, $e);
     }
     return $result;
 }
 public function testInvalidExpression()
 {
     $this->setExpectedException(ParserException::class);
     $model = new ContentModel();
     $expression = new MethodEvaluationExpression('getFoo', $model);
     $expression->getResult();
 }