Add a node to the criteria

@param  Node $expr,...
@return SelectManager
176656
function where($expr)
    {
        foreach (func_get_args() as $expr) {
            $this->getNodes()->restrictions[] = $expr;
        }

        return $this;
    }
1211401
public function addNode(Node $node)
    {
        foreach ($this->nodes as $n) {
            if ($n->getIdentifier() === $node->getIdentifier()) {
                throw new SchemaDefinitionException(sprintf('The node with Identifier "%s" has already been declared', $node->getIdentifier()));
            }
        }

        return $this->nodes->add($node);
    }
845450
function group($expr)
    {
        if (null === $expr) {
            $this->nodes->groups = array();
        } else {
            $this->nodes->groups[] = new Group($expr);
        }
        return $this;
    }
1150976
public function dispatch(Expression $expr, ?AbstractNode $parentNode = null)
    {
        if ($parentNode === null) {
            $parentNode = $this->queryBuilder->where();
        }

        switch (true) {
            case $expr instanceof Comparison:
                return $this->walkComparison($expr, $parentNode);
            case $expr instanceof CompositeExpression:
                return $this->walkCompositeExpression($expr, $parentNode);
        }

        throw new \RuntimeException('Unknown Expression: ' . get_class($expr));
    }
207973
void add(Node node) {

		if (!(node instanceof Criteria)) {
			throw new IllegalArgumentException("Can only add instances of Criteria");
		}

		node.setParent(this);

		boolean containsNearFunction = this.siblings.stream().anyMatch(criteria -> criteria.getPredicates().stream()
				.anyMatch(predicate -> predicate.getKey().equalsIgnoreCase("$within")));

		Criteria criteria = (Criteria) node;
		if (containsNearFunction) {
			this.siblings.add(0, criteria);
		} else {
			this.siblings.add(criteria);
		}

		this.mostRecentSibling = node;
	}
967628
function where($expr)
    {
        $select = $this->from();
        foreach (func_get_args() as $expr) {
            $select->where($expr);
        }
        return $select;
    }
878844
protected function compileExpression($expr)
    {
        $expr = trim($expr);

        if (strncasecmp($expr, 'SELECT ', 7) === 0) {
            // It is as a raw subquery. Skip this, because the Builder of the subquery has should quoted this already.
            return  $expr;
        }

        $n = strlen($expr);
        $i = 0;
        while ($i < $n) {
            $ch = $expr[$i];
            if (stripos('abcdefghijklmnopqrstuvwxyz_', $ch) !== false) {
                // Is it a table/field/alias or a function?
                $k = $i; // first index of this part
                while (++$i < $n && stripos('abcdefghijklmnopqrstuvwxyz0123456789$_', $expr[$i]) !== false);
                $name = substr($expr, $k, $i - $k);
                $j = $i; // first index of the next part
                if (in_array(strtoupper($name), static::$keywords)) {
                    $expr = substr($expr, 0, $k) . strtoupper($name) . substr($expr, $j);
                }
                else {
                    while ($i < $n && $expr[$i] == ' ') ++$i; // skip spaces
                    if ($i < $n && $expr[$i] == '(') {
                        // It's a function! Take the arguments an translate the function if needed...
                        $args = [];
                        $braces = 1;
                        $j = $i + 1; // first index of the argument
                        while (++$i < $n && $braces > 0) {
                            $ch = $expr[$i];
                            if ($ch == ')') {
                                $braces--;
                            }
                            else if ($ch == '(') {
                                $braces++;
                            }
                            else if ($braces == 1 && $ch == ',') {
                                $args[] = substr($expr, $j, $i - $j);
                                $j = $i + 1;
                            }
                            else if ($ch == '"' || $ch == "'" || $ch == '`' || $ch == '[') { // masked literal
                                $c = $ch == '[' ? ']' : $ch;
                                while (++$i < $n && $expr[$i] != $c);
                            }
                            else if ($ch == '-' && $i + 2 < $n && $expr[$i + 1] == '-' && $expr[$i + 2] == ' ') { // comment
                                $i += 2;
                                while (++$i < $n && $expr[$i] != PHP_EOL);
                            }
                        }
                        if ($i - $j - 1 > 0) {
                            $args[] = substr($expr, $j, $i - $j - 1);
                        }

                        $args = array_map([$this, 'compileExpression'], $args);
//                        $args = array_map(function ($arg) {
//                            return $this->compileExpression($arg);
//                        }, $args);
                        $repl = $this->compileFunction($name, $args);
                        $j = $i; // first index of the next part
                    }
                    else {
                        // It's a table, field, or alias! Quote this one!
                        $repl = $this->db->quoteName($name);
                    }
                    // Replace the original term with the quoted part.
                    $expr = substr($expr, 0, $k) . $repl . substr($expr, $j);
                    $j = strlen($repl) - $j + $k; // difference of characters after replacing
                    $i += $j;
                    $n += $j;
                }
            }
            else if ($ch == '(') {
                // Is it a embedded subquery?
                while (++$i < $n && $expr[$i] == ' '); // skip spaces
                if (strcasecmp(substr($expr, $i, 7), 'SELECT ') === 0) {
                    // Yes, it is a embedded subquery! Skip this, because the Builder of the subquery has should quoted this already.
                    $i += 6;
                    $braces = 1;
                    while (++$i < $n && $braces > 0) {
                        $ch = $expr[$i];
                        if ($ch == ')') {
                            $braces--;
                        }
                        else if ($ch == '(') {
                            $braces++;
                        }
                        else if ($ch == '"' || $ch == "'" || $ch == '`' || $ch == '[') { // masked literal
                            $c = $ch == '[' ? ']' : $ch;
                            while (++$i < $n && $expr[$i] != $c);
                        }
                        else if ($ch == '-' && $i + 2 < $n && $expr[$i + 1] == '-' && $expr[$i + 2] == ' ') { // comment
                            $i += 2;
                            while (++$i < $n && $expr[$i] != PHP_EOL);
                        }
                    }
                }
            }
            else if ($ch == ':') { // named placeholder
                while (++$i < $n && stripos('abcdefghijklmnopqrstuvwxyz0123456789$_', $expr[$i]) !== false);
                ++$i;
            }
            else if ($ch == '"' || $ch == "'" || $ch == '`' || $ch == '[') { // masked literal
                $c = $ch == '[' ? ']' : $ch;
                while (++$i < $n && $expr[$i] != $c);
                ++$i;
            }
            else if ($ch == '-' && $i + 2 < $n && $expr[$i + 1] == '-' && $expr[$i + 2] == ' ') { // comment
                $j = $i + 2;
                while (++$j < $n && $expr[$j] != PHP_EOL);
                ++$j;
                // Remove the comment
                $expr = substr($expr, 0, $i) . substr($expr, $j);
                $n -= $j - $i; // difference of characters after replacing
            }
            else {
                ++$i;
            }
        }

        return $expr;
    }
1132457
public function addSelect($select)
    {
        if (null === $select) {
            return $this;
        }
        if (is_array($select)) {
            $t = [];
            foreach ($select as $field => $alias) {
                if (is_int($field)) {
                    $alias = $this->quoteColumnName($alias);
                    array_push($t, "{$alias}");
                } else {
                    $field = $this->quoteColumnName($field);
                    $alias = $this->quoteColumnName($alias);
                    array_push($t, "{$field} AS {$alias}");
                }
            }
            $select = implode(',', $t);
        }
        if (isset($this->query['select']) && !empty($this->query['select'])) {
            $select = "{$this->query['select']},{$select}";
        }
        $this->query['select'] = $select;
        return $this;
    }
1313185
public function addSelect($void = null)
    {
        $this->ensureNoArguments(__METHOD__, $void);

        return $this->setChild(new SelectAdd($this));
    }
143236
protected function add()
    {
        $nodeRef = $this->buildCmsNodeRef($slugKey = null);

        if (!$this->buttonPushed()) {

            $node = $nodeRef->generateNode();
            $node->setNodePartials(new NodePartials('all', 'fields', 'fields'));

            $this->NodeMapper->defaultsOnNode($node);

            $this->NodeBinder->bindPersistentFields($node, $this->getErrors(), $this->params, $this->rawParams);
            $this->NodeBinder->fireAddBindEvents($node, $this->getErrors(), $this->params, $this->rawParams);

            $location = 'load';
            $this->Events->trigger('NodeCmsController.add'.'.'.$location, $this->errors, $this->templateVars, $node);
            foreach ((array)$nodeRef->getElement()->getAspects() as $aspect)
                $this->Events->trigger('NodeCmsController.@'.$aspect->Slug.'.'.'add'.'.'.$location, $this->errors, $this->templateVars, $node);

            if($node->hasTitle() && !$node->hasSlug())
                $node->Slug = SlugUtils::createSlug($node->Title, $node->getNodeRef()->getElement()->AllowSlugSlashes);

            $this->bindNodeToActionDatasource($node);

            //show form view (action_form_view)
            return new View($this->formView());

            //*** at this point the only subsequent actions will result from button presses
        }

        if ($this->cancelButtonPushed() || $this->deleteConfirmButtonPushed()) {

            // $this->service->delete($id);

            $view = new View($this->cancelView());

            $location = 'cancel';
            $this->Events->trigger('NodeCmsController.add'.'.'.$location,
                                    $this->errors, $this->templateVars, $view);
            foreach ((array)$nodeRef->getElement()->getAspects() as $aspect)
                $this->Events->trigger('NodeCmsController.@'.$aspect->Slug.'.'.'add'.'.'.$location,
                                        $this->errors, $this->templateVars, $view);

            //redirect to pages list (action_cancel_view)
            return $view;
        }

        if ($this->saveButtonPushed() || $this->saveAndContinueButtonPushed() || $this->saveAndNewButtonPushed()) {

            //get default form backing object
            // $page = $this->service->getByID($id);
            try {
                $nodeRef = $this->buildCmsNodeRef($slugKey = 'Slug');

                $node = $nodeRef->generateNode();

                //bind posted params to form backing object
                $this->NodeBinder->bindPersistentFields($node, $this->getErrors(), $this->params, $this->rawParams);
                $this->NodeBinder->fireAddBindEvents($node, $this->getErrors(), $this->params, $this->rawParams);

                //FIRE EVENTS FOR PRE-ADD
                $location = 'pre';
                $this->Events->trigger('NodeCmsController.add'.'.'.$location,
                                        $this->errors, $this->templateVars, $node);
                foreach((array)$nodeRef->getElement()->getAspects() as $aspect)
                    $this->Events->trigger('NodeCmsController.@'.$aspect->Slug.'.'.'add'.'.'.$location,
                                            $this->errors, $this->templateVars, $node);

                // check permissions
                // $this->checkAddPermission($node);
                $this->checkNonce();

                $this->getErrors()->throwOnError();

                $this->RegulatedNodeService->add($node);

                $location = 'post';
                $this->Events->trigger('NodeCmsController.add'.'.'.$location,
                                            $this->errors, $this->templateVars, $node);
                foreach((array)$nodeRef->getElement()->getAspects() as $aspect)
                    $this->Events->trigger('NodeCmsController.@'.$aspect->Slug.'.'.'add'.'.'.$location,
                                            $this->errors, $this->templateVars, $node);


            } catch(ValidationException $ve) {
                $location = 'validationException';
                $this->Events->trigger('NodeCmsController.add'.'.'.$location,
                                            $this->errors, $this->templateVars, $node);
                foreach ((array)$nodeRef->getElement()->getAspects() as $aspect)
                    $this->Events->trigger('NodeCmsController.@'.$aspect->Slug.'.'.'add'.'.'.$location,
                                            $this->errors, $this->templateVars, $node);

                $this->RegulatedNodeService->resolveLinkedNodes($node, $node->getNodePartials(), true);

                //bind form backing object to datasource
                $this->bindNodeToActionDatasource($node);

                //re-throw validationexception, which shows form view
                throw $ve;
            } catch (Exception $e) {

                $this->ErrorHandler->sendErrorEmail($e);

                $this->errors->addGlobalError($e->getCode(), $e->getMessage());

                if(!empty($node))
                {
                    $location = 'validationException';
                    $this->Events->trigger('NodeCmsController.add'.'.'.$location,
                                                $this->errors, $this->templateVars, $node);

                    foreach((array)$nodeRef->getElement()->getAspects() as $aspect)
                        $this->Events->trigger('NodeCmsController.@'.$aspect->Slug.'.'.'add'.'.'.$location,
                                                $this->errors, $this->templateVars, $node);

                    $this->RegulatedNodeService->resolveLinkedNodes($node, $node->getNodePartials(), true);

                    //bind form backing object to datasource
                    $this->bindNodeToActionDatasource($node);
                }

                //re-throw validationexception, which shows form view
                throw new ValidationException($this->errors);
            }

            $this->Session->setFlashAttribute('saved', true);

            if ($this->saveButtonPushed())
                //redirect to list (action_success_view)
                return new View($this->successView());

            elseif($this->saveAndContinueButtonPushed())
                //redirect to edit (action_continue_view)
                return new View($this->continueView(), array('slug'=> $node->getSlug()));

            elseif($this->saveAndNewButtonPushed())
                // redirect to new edit (action_new_view)
                return new View($this->newView(true), array('newslug'=> $node->getSlug()));

        }

        throw new Exception("unsupported button for this action");
    }
682281
public function resolveExpressionNodeToType($expr)
    {
        // PARENTHESIZED EXPRESSION
        // Retrieve inner expression from parenthesized expression
        while ($expr instanceof Node\Expression\ParenthesizedExpression) {
            $expr = $expr->expression;
        }

        if ($expr == null || $expr instanceof PhpParser\MissingToken || $expr instanceof PhpParser\SkippedToken) {
            // TODO some members are null or Missing/SkippedToken
            // How do we handle this more generally?
            return new Types\Mixed_;
        }

        // VARIABLE
        //   $this -> Type\this
        //   $myVariable -> type of corresponding assignment expression
        if ($expr instanceof Node\Expression\Variable || $expr instanceof Node\UseVariableName) {
            if ($expr->getName() === 'this') {
                return new Types\Object_(new Fqsen('\\' . $this->getContainingClassFqn($expr)));
            }
            // Find variable definition (parameter or assignment expression)
            $defNode = $this->resolveVariableToNode($expr);
            if ($defNode instanceof Node\Expression\AssignmentExpression || $defNode instanceof Node\UseVariableName) {
                return $this->resolveExpressionNodeToType($defNode);
            }
            if ($defNode instanceof Node\ForeachKey || $defNode instanceof Node\ForeachValue) {
                return $this->getTypeFromNode($defNode);
            }
            if ($defNode instanceof Node\Parameter) {
                return $this->getTypeFromNode($defNode);
            }
        }

        // FUNCTION CALL
        // Function calls are resolved to type corresponding to their FQN
        if ($expr instanceof Node\Expression\CallExpression &&
            !(
                $expr->callableExpression instanceof Node\Expression\ScopedPropertyAccessExpression ||
                $expr->callableExpression instanceof Node\Expression\MemberAccessExpression)
        ) {
            // Find the function definition
            if ($expr->callableExpression instanceof Node\Expression) {
                // Cannot get type for dynamic function call
                return new Types\Mixed_;
            }

            if ($expr->callableExpression instanceof Node\QualifiedName) {
                $fqn = $expr->callableExpression->getResolvedName() ?? $expr->callableExpression->getNamespacedName();
                $fqn .= '()';
                $def = $this->index->getDefinition($fqn, true);
                if ($def !== null) {
                    return $def->type;
                }
            }
        }

        // TRUE / FALSE / NULL
        // Resolve true and false reserved words to Types\Boolean
        if ($expr instanceof Node\ReservedWord) {
            $token = $expr->children->kind;
            if ($token === PhpParser\TokenKind::TrueReservedWord || $token === PhpParser\TokenKind::FalseReservedWord) {
                return new Types\Boolean;
            }

            if ($token === PhpParser\TokenKind::NullReservedWord) {
                return new Types\Null_;
            }
        }

        // CONSTANT FETCH
        // Resolve constants by retrieving corresponding definition type from FQN
        if (ParserHelpers\isConstantFetch($expr)) {
            $fqn = (string)$expr->getNamespacedName();
            $def = $this->index->getDefinition($fqn, true);
            if ($def !== null) {
                return $def->type;
            }
        }

        // MEMBER CALL EXPRESSION/SCOPED PROPERTY CALL EXPRESSION
        //   The type of the member/scoped property call expression is the type of the method, so resolve the
        //   type of the callable expression.
        if ($expr instanceof Node\Expression\CallExpression && (
            $expr->callableExpression instanceof Node\Expression\MemberAccessExpression ||
            $expr->callableExpression instanceof Node\Expression\ScopedPropertyAccessExpression)
        ) {
            return $this->resolveExpressionNodeToType($expr->callableExpression);
        }

        // MEMBER ACCESS EXPRESSION
        if ($expr instanceof Node\Expression\MemberAccessExpression) {
            if ($expr->memberName instanceof Node\Expression) {
                return new Types\Mixed_;
            }
            $var = $expr->dereferencableExpression;

           // Resolve object
            $objType = $this->resolveExpressionNodeToType($var);
            if (!($objType instanceof Types\Compound)) {
                $objType = new Types\Compound([$objType]);
            }
            for ($i = 0; $t = $objType->get($i); $i++) {
                if ($t instanceof Types\This) {
                    $classFqn = self::getContainingClassFqn($expr);
                    if ($classFqn === null) {
                        return new Types\Mixed_;
                    }
                } else if (!($t instanceof Types\Object_) || $t->getFqsen() === null) {
                    return new Types\Mixed_;
                } else {
                    $classFqn = substr((string)$t->getFqsen(), 1);
                }
                $add = '->' . $expr->memberName->getText($expr->getFileContents());
                if ($expr->parent instanceof Node\Expression\CallExpression) {
                    $add .= '()';
                }
                $classDef = $this->index->getDefinition($classFqn);
                if ($classDef !== null) {
                    foreach ($classDef->getAncestorDefinitions($this->index, true) as $fqn => $def) {
                        $def = $this->index->getDefinition($fqn . $add);
                        if ($def !== null) {
                            if ($def->type instanceof Types\This || $def->type instanceof Types\Self_) {
                                return new Types\Object_(new Fqsen('\\' . $classFqn));
                            }
                            return $def->type;
                        }
                    }
                }
            }
        }

        // SCOPED PROPERTY ACCESS EXPRESSION
        if ($expr instanceof Node\Expression\ScopedPropertyAccessExpression) {
            $classType = $this->resolveClassNameToType($expr->scopeResolutionQualifier);
            if (!($classType instanceof Types\Object_) || $classType->getFqsen() === null) {
                return new Types\Mixed_;
            }
            $fqn = substr((string)$classType->getFqsen(), 1) . '::';

            // TODO is there a cleaner way to do this?
            $fqn .= $expr->memberName->getText() ?? $expr->memberName->getText($expr->getFileContents());
            if ($expr->parent instanceof Node\Expression\CallExpression) {
                $fqn .= '()';
            }

            $def = $this->index->getDefinition($fqn);
            if ($def === null) {
                return new Types\Mixed_;
            }
            return $def->type;
        }

        // OBJECT CREATION EXPRESSION
        //   new A() => resolves to the type of the class type designator (A)
        //   TODO: new $this->a => resolves to the string represented by "a"
        if ($expr instanceof Node\Expression\ObjectCreationExpression) {
            return $this->resolveClassNameToType($expr->classTypeDesignator);
        }

        // CLONE EXPRESSION
        //   clone($a) => resolves to the type of $a
        if ($expr instanceof Node\Expression\CloneExpression) {
            return $this->resolveExpressionNodeToType($expr->expression);
        }

        // ASSIGNMENT EXPRESSION
        //   $a = $myExpression => resolves to the type of the right-hand operand
        if ($expr instanceof Node\Expression\AssignmentExpression) {
            return $this->resolveExpressionNodeToType($expr->rightOperand);
        }

        // TERNARY EXPRESSION
        //   $condition ? $ifExpression : $elseExpression => reslves to type of $ifCondition or $elseExpression
        //   $condition ?: $elseExpression => resolves to type of $condition or $elseExpression
        if ($expr instanceof Node\Expression\TernaryExpression) {
            // ?:
            if ($expr->ifExpression === null) {
                return new Types\Compound([
                    $this->resolveExpressionNodeToType($expr->condition), // TODO: why?
                    $this->resolveExpressionNodeToType($expr->elseExpression)
                ]);
            }
            // Ternary is a compound of the two possible values
            return new Types\Compound([
                $this->resolveExpressionNodeToType($expr->ifExpression),
                $this->resolveExpressionNodeToType($expr->elseExpression)
            ]);
        }

        // NULL COALLESCE
        //   $rightOperand ?? $leftOperand => resolves to type of $rightOperand or $leftOperand
        if ($expr instanceof Node\Expression\BinaryExpression && $expr->operator->kind === PhpParser\TokenKind::QuestionQuestionToken) {
            // ?? operator
            return new Types\Compound([
                $this->resolveExpressionNodeToType($expr->leftOperand),
                $this->resolveExpressionNodeToType($expr->rightOperand)
            ]);
        }

        // BOOLEAN EXPRESSIONS: resolve to Types\Boolean
        //   (bool) $expression
        //   !$expression
        //   empty($var)
        //   isset($var)
        //   >, >=, <, <=, &&, ||, AND, OR, XOR, ==, ===, !=, !==
        if (
            ParserHelpers\isBooleanExpression($expr)

            || ($expr instanceof Node\Expression\CastExpression && $expr->castType->kind === PhpParser\TokenKind::BoolCastToken)
            || ($expr instanceof Node\Expression\UnaryOpExpression && $expr->operator->kind === PhpParser\TokenKind::ExclamationToken)
            || $expr instanceof Node\Expression\EmptyIntrinsicExpression
            || $expr instanceof Node\Expression\IssetIntrinsicExpression
        ) {
            return new Types\Boolean;
        }

        // STRING EXPRESSIONS: resolve to Types\String
        //   [concatenation] .=, .
        //   [literals] "hello", \b"hello", \B"hello", 'hello', \b'hello', HEREDOC, NOWDOC
        //   [cast] (string) "hello"
        //
        //   TODO: Magic constants (__CLASS__, __DIR__, __FUNCTION__, __METHOD__, __NAMESPACE__, __TRAIT__, __FILE__)
        if (
            ($expr instanceof Node\Expression\BinaryExpression &&
                ($expr->operator->kind === PhpParser\TokenKind::DotToken || $expr->operator->kind === PhpParser\TokenKind::DotEqualsToken)) ||
            $expr instanceof Node\StringLiteral ||
            ($expr instanceof Node\Expression\CastExpression && $expr->castType->kind === PhpParser\TokenKind::StringCastToken)
        ) {
            return new Types\String_;
        }

        // BINARY EXPRESSIONS:
        // Resolve to Types\Integer if both left and right operands are integer types, otherwise Types\Float
        //   [operator] +, -, *, **
        //   [assignment] *=, **=, -=, +=
        // Resolve to Types\Float
        //   [assignment] /=
        if (
            $expr instanceof Node\Expression\BinaryExpression &&
            ($operator = $expr->operator->kind)
            && ($operator === PhpParser\TokenKind::PlusToken ||
                $operator === PhpParser\TokenKind::AsteriskAsteriskToken ||
                $operator === PhpParser\TokenKind::AsteriskToken ||
                $operator === PhpParser\TokenKind::MinusToken ||

                // Assignment expressions (TODO: consider making this a type of AssignmentExpression rather than kind of BinaryExpression)
                $operator === PhpParser\TokenKind::AsteriskEqualsToken||
                $operator === PhpParser\TokenKind::AsteriskAsteriskEqualsToken ||
                $operator === PhpParser\TokenKind::MinusEqualsToken ||
                $operator === PhpParser\TokenKind::PlusEqualsToken
            )
        ) {
            if (
                $this->resolveExpressionNodeToType($expr->leftOperand) instanceof Types\Integer
                && $this->resolveExpressionNodeToType($expr->rightOperand) instanceof Types\Integer
            ) {
                return new Types\Integer;
            }
            return new Types\Float_;
        } else if (
            $expr instanceof Node\Expression\BinaryExpression &&
            $expr->operator->kind === PhpParser\TokenKind::SlashEqualsToken
        ) {
            return new Types\Float_;
        }

        // INTEGER EXPRESSIONS: resolve to Types\Integer
        //   [literal] 1
        //   [operator] <=>, &, ^, |
        //   TODO: Magic constants (__LINE__)
        if (
            // TODO: consider different Node types of float/int, also better property name (not "children")
            ($expr instanceof Node\NumericLiteral && $expr->children->kind === PhpParser\TokenKind::IntegerLiteralToken) ||
            $expr instanceof Node\Expression\BinaryExpression && (
                ($operator = $expr->operator->kind)
                && ($operator === PhpParser\TokenKind::LessThanEqualsGreaterThanToken ||
                    $operator === PhpParser\TokenKind::AmpersandToken ||
                    $operator === PhpParser\TokenKind::CaretToken ||
                    $operator === PhpParser\TokenKind::BarToken)
            )
        ) {
            return new Types\Integer;
        }

        // FLOAT EXPRESSIONS: resolve to Types\Float
        //   [literal] 1.5
        //   [operator] /
        //   [cast] (double)
        if (
            $expr instanceof Node\NumericLiteral && $expr->children->kind === PhpParser\TokenKind::FloatingLiteralToken ||
            ($expr instanceof Node\Expression\CastExpression && $expr->castType->kind === PhpParser\TokenKind::DoubleCastToken) ||
            ($expr instanceof Node\Expression\BinaryExpression && $expr->operator->kind === PhpParser\TokenKind::SlashToken)
        ) {
            return new Types\Float_;
        }

        // ARRAY CREATION EXPRESSION:
        // Resolve to Types\Array (Types\Compound of value and key types)
        //  [a, b, c]
        //  [1=>"hello", "hi"=>1, 4=>[]]s
        if ($expr instanceof Node\Expression\ArrayCreationExpression) {
            $valueTypes = [];
            $keyTypes = [];
            if ($expr->arrayElements !== null) {
                foreach ($expr->arrayElements->getElements() as $item) {
                    $valueTypes[] = $this->resolveExpressionNodeToType($item->elementValue);
                    $keyTypes[] = $item->elementKey ? $this->resolveExpressionNodeToType($item->elementKey) : new Types\Integer;
                }
            }
            $valueTypes = array_unique($valueTypes);
            $keyTypes = array_unique($keyTypes);
            if (empty($valueTypes)) {
                $valueType = null;
            } else if (count($valueTypes) === 1) {
                $valueType = $valueTypes[0];
            } else {
                $valueType = new Types\Compound($valueTypes);
            }
            if (empty($keyTypes)) {
                $keyType = null;
            } else if (count($keyTypes) === 1) {
                $keyType = $keyTypes[0];
            } else {
                $keyType = new Types\Compound($keyTypes);
            }
            return new Types\Array_($valueType, $keyType);
        }

        // SUBSCRIPT EXPRESSION
        // $myArray[3]
        // $myArray{"hello"}
        if ($expr instanceof Node\Expression\SubscriptExpression) {
            $varType = $this->resolveExpressionNodeToType($expr->postfixExpression);
            if (!($varType instanceof Types\Array_)) {
                return new Types\Mixed_;
            }
            return $varType->getValueType();
        }

        // SCRIPT INCLUSION EXPRESSION
        //   include, require, include_once, require_once
        if ($expr instanceof Node\Expression\ScriptInclusionExpression) {
            // TODO: resolve path to PhpDocument and find return statement
            return new Types\Mixed_;
        }

        if ($expr instanceof Node\QualifiedName) {
            return $this->resolveClassNameToType($expr);
        }

        return new Types\Mixed_;
    }
1075916
public function addOr(Expr $subexpression /*, $subexpression2, ... */)
    {
        $or = new Condition\Logical\AddOr;
        $or->add(...array_map(
            function (Expr $expr) {
                return $expr->condition;
            },
            func_get_args()
        ));

        $this->addCondition($or);

        return $this;
    }
888477
public function selectRaw($expression, array $bindings = [])
    {
        $this->addSelect(new Expression($expression));

        if ($bindings) {
            $this->addBinding($bindings, 'select');
        }

        return $this;
    }
458837
function add(Expr $next) {
		if ($this->isNull()) {
			throw new \UnexpectedValueException("Cannot add anything to NULL");
		}
		if ($this->next) {
			$this->next->add($next);
		} else {
			$this->next = $next;
		}
		return $this;
	}
447073
protected function _addResultColumn($expr, $alias = null)
        {
            if (!is_null($alias)) {
                $expr .= " AS " . $this->_quoteIdentifier($alias);
            }

            if ($this->_using_default_resultColumns) {
                $this->_resultColumns = array($expr);
                $this->_using_default_resultColumns = false;
            } else {
                $this->_resultColumns[] = $expr;
            }

            return $this;
        }
69244
public function add(\DOMElement $node) {
		$name = $node->getAttribute('name');
		if($this->has($name))
			$this->get($name)->addChoice($node);
		else
			$this->set($name, new Field($node));
	}
333426
protected function appendXPathOutput(DOMElement $parentNode, $expr)
	{
		$this->appendElement($parentNode, 'output', htmlspecialchars(trim($expr)))
		     ->setAttribute('type', 'xpath');
	}