public function resolveVariableToNode($var)
    {
        $n = $var;
        // When a use is passed, start outside the closure to not return immediately
        // Use variable vs variable parsing?
        if ($var instanceof Node\UseVariableName) {
            $n = $var->getFirstAncestor(Node\Expression\AnonymousFunctionCreationExpression::class)->parent;
            $name = $var->getName();
        } else if ($var instanceof Node\Expression\Variable || $var instanceof Node\Parameter) {
            $name = $var->getName();
        } else {
            throw new \InvalidArgumentException('$var must be Variable, Param or ClosureUse, not ' . get_class($var));
        }
        if (empty($name)) {
            return null;
        }

        $shouldDescend = function ($nodeToDescand) {
            // Make sure not to decend into functions or classes (they represent a scope boundary)
            return !($nodeToDescand instanceof PhpParser\FunctionLike || $nodeToDescand instanceof PhpParser\ClassLike);
        };

        // Traverse the AST up
        do {
            // If a function is met, check the parameters and use statements
            if ($n instanceof PhpParser\FunctionLike) {
                if ($n->parameters !== null) {
                    foreach ($n->parameters->getElements() as $param) {
                        if ($param->getName() === $name) {
                            return $param;
                        }
                    }
                }
                // If it is a closure, also check use statements
                if ($n instanceof Node\Expression\AnonymousFunctionCreationExpression &&
                    $n->anonymousFunctionUseClause !== null &&
                    $n->anonymousFunctionUseClause->useVariableNameList !== null) {
                    foreach ($n->anonymousFunctionUseClause->useVariableNameList->getElements() as $use) {
                        if ($use->getName() === $name) {
                            return $use;
                        }
                    }
                }
                break;
            }

            // Check each previous sibling node and their descendents for a variable assignment to that variable
            // Each previous sibling could contain a declaration of the variable
            while (($prevSibling = $n->getPreviousSibling()) !== null && $n = $prevSibling) {

                // Check the sibling itself
                if (self::isVariableDeclaration($n, $name)) {
                    return $n;
                }

                // Check descendant of this sibling (e.g. the children of a previous if block)
                foreach ($n->getDescendantNodes($shouldDescend) as $descendant) {
                    if (self::isVariableDeclaration($descendant, $name)) {
                        return $descendant;
                    }
                }
            }
        } while (isset($n) && $n = $n->parent);
        // Return null if nothing was found
        return null;
    }