/**
  * @param string $logical
  * @param array  $expressions <ExpressionInterface>
  *
  * @throws ExpressionException
  */
 public function __construct($logical, array $expressions)
 {
     $this->logical = $logical;
     foreach ($expressions as $expr) {
         if (!$expr instanceof ExpressionInterface) {
             throw ExpressionException::notInstanceOfExpression();
         }
         $this->_expression[] = $expr;
     }
 }
 /**
  * Dispatch walking an expression to the appropriate handler.
  *
  * @param ExpressionInterface $expr
  *
  * @return mixed
  *
  * @throws ExpressionException
  */
 public function dispatch(ExpressionInterface $expr)
 {
     switch (true) {
         case $expr instanceof Comparison:
             return $this->walkComparison($expr);
         case $expr instanceof CompositeExpression:
             return $this->walkCompositeExpression($expr);
         default:
             throw ExpressionException::unknownExpression($expr);
     }
 }
 /**
  * Convert a composite expression into the target query language output.
  *
  * @param CompositeExpression $expr
  *
  * @return mixed
  *
  * @throws ExpressionException
  */
 public function walkCompositeExpression(CompositeExpression $expr)
 {
     $expressionList = array();
     foreach ($expr->getExpressionList() as $expression) {
         $expressionList[] = $this->dispatch($expression);
     }
     switch ($expr->getLogical()) {
         case CompositeExpression::LOGICAL_AND:
             return $this->andExpression($expressionList);
         case CompositeExpression::LOGICAL_OR:
             return $this->orExpression($expressionList);
         default:
             throw ExpressionException::unknownCompositeLogical($expr->getLogical());
     }
 }