                 closed_over = false
                 # look up our environment stack for the decl for it.
                 env = env.parent
+                intervening_function = false
                 while env?
                         if env.decls?.has n.name
-                                closed_over = true
+                                closed_over = intervening_function
                                 env = null
                         else
+                                if env.exp.type isnt BlockStatement # if it's a function
+                                        intervening_function = true
                                 env = env.parent
+                                
 
                 # if we found it higher on the function stack, we need to walk back up the stack forcing environments along the way, and make
                 # sure the frame that declares it knows that something down the stack closes over it.


        visitFunction: (n) ->
                current_env = @envs.top if @envs.depth > 0
                new_env = { id: @env_id, decls: (if n.ejs_decls? then n.ejs_decls else new Set), closed: new Set, parent: current_env }
                @env_id += 1
                n.ejs_env = new_env
                @envs.push new_env

                        return b.varDeclaration(b.identifier(n.id.name), func_exp)


class ConvertLetLoopVariables extends TransformPass
        constructor: (options, @filename) ->
                super

        visitForStatement: (n) ->
                return n if n.init?.type isnt VariableDeclaration
                return n if n.init?.kind isnt 'let'

                #
                # we have a loop that looks like:
                #
                #  for (let x = ...; $test; $update) {
                #      /* body */
                #  }
                #
                # we desugar this to:
                #
                #  for (var %loop_x = ...; $test(with x replaced with %loop_x); $update(with x replaced with %loop_x) {
                #    let x = %loop_x;
                #    try {
                #      /* body */
                #    }
                #    finally {
                #      %loop_x = x;
                #    }
                #  }
        
# hoists all vars to the start of the enclosing function, replacing
# any initializer with an assignment expression.  We also take the
# opportunity to convert the vars to lets at this point so by the time
