public void VisitNode(JSFunctionExpression fn)
        {
            if (Stack.OfType <JSFunctionExpression>().Skip(1).FirstOrDefault() != null)
            {
                var nested = new IntroduceVariableDeclarations(fn.AllVariables, TypeInfo);
                nested.Visit(fn);
                return;
            }

            var existingDeclarations = new HashSet <string>(
                fn.AllChildrenRecursive.OfType <JSVariableDeclarationStatement>()
                .SelectMany(
                    (vds) =>
                    from vd in vds.Declarations
                    select((JSVariable)vd.Left).Identifier
                    ).Union(
                    from tcb in fn.AllChildrenRecursive.OfType <JSTryCatchBlock>()
                    where tcb.CatchVariable != null
                    select tcb.CatchVariable.Identifier
                    )
                );

            foreach (var v_ in from v in Variables.Values
                     where !v.IsParameter &&
                     !existingDeclarations.Contains(v.Identifier)
                     select v)
            {
                ToDeclare.Add(v_);
            }

            VisitChildren(fn);

            if (ToDeclare.Count > 0)
            {
                fn.Body.Statements.Insert(
                    0, new JSVariableDeclarationStatement(
                        (from v in ToDeclare
                         select new JSBinaryOperatorExpression(
                             JSOperator.Assignment, v,
                             v.DefaultValue,
                             v.Type
                             )).ToArray()
                        )
                    );
            }
        }
        public void VisitNode(JSFunctionExpression fn)
        {
            if (Stack.OfType<JSFunctionExpression>().Skip(1).FirstOrDefault() != null) {
                var nested = new IntroduceVariableDeclarations(fn.AllVariables, TypeInfo);
                nested.Visit(fn);
                return;
            }

            var existingDeclarations = new HashSet<string>(
                fn.AllChildrenRecursive.OfType<JSVariableDeclarationStatement>()
                .SelectMany(
                    (vds) =>
                        from vd in vds.Declarations
                        select ((JSVariable)vd.Left).Identifier
                ).Union(
                    from tcb in fn.AllChildrenRecursive.OfType<JSTryCatchBlock>()
                    where tcb.CatchVariable != null
                    select tcb.CatchVariable.Identifier
                )
            );

            foreach (var v_ in from v in Variables.Values
                               where !v.IsParameter &&
                                     !existingDeclarations.Contains(v.Identifier)
                               select v)
            {
                ToDeclare.Add(v_);
            }

            VisitChildren(fn);

            if (ToDeclare.Count > 0)
                fn.Body.Statements.Insert(
                    0, new JSVariableDeclarationStatement(
                        (from v in ToDeclare
                         select new JSBinaryOperatorExpression(
                            JSOperator.Assignment, v,
                            v.DefaultValue,
                            v.IdentifierType
                        )).ToArray()
                    )
                );
        }