anchor.diff:                [identifier(loopName)])]),
             block([AstFactory.functionExpressionInvocation(
                 identifier(breakName), [nullLiteral()])])));
  -      });
  -
  -      var loopBlock = currentBlock = emptyBlock();
  -      addStatement(
  -          AstFactory.functionDeclarationStatement(null, null, continueName,
  -              functionExpression(['_'], continueBlock)));
  -      breakTargets.add(identifier(breakName));
  -      continueTargets.add(identifier(continueName));
  -      visit(node.body)(f, r, () {
  -        addStatement(
  -            AstFactory.functionExpressionInvocation(
  -                identifier(continueName), [nullLiteral()]));
  -      });
  -      breakTargets.removeLast();
  -      continueTargets.removeLast();
  -
  -      currentBlock = savedBlock;
  -      addStatement(
  -          AstFactory.functionDeclarationStatement(null, null, breakName,
  -              functionExpression(['_'], breakBlock)));
  -      addStatement(
  -          AstFactory.functionDeclarationStatement(null, null, loopName,
  -              functionExpression(['_'], loopBlock)));
  +    });
  +
  +    var loopBlock = currentBlock = emptyBlock();
  +    addStatement(
  +        AstFactory.functionDeclarationStatement(null, null, continueName,
  +            functionExpression(['_'], continueBlock)));
  +    breakTargets.add(identifier(breakName));
  +    continueTargets.add(identifier(continueName));
  +    visit(node.body)(f, r, () {
         addStatement(
             AstFactory.functionExpressionInvocation(
  -              identifier(loopName), [nullLiteral()]));
  -    };
  -  }
  -
  -  StatementTransformer visitExpressionStatement(ast.ExpressionStatement node) {
  -    return (ErrorCont f, ReturnCont r, StatementCont s) {
  -      return visitExpression(node.expression)(f, (expr) {
  -        addStatement(expr);
  -        return s();
  -      });
  -    };
  -  }
  -
  -  StatementTransformer visitForStatement(ast.ForStatement node) {
  -    translateUpdaters(List<ast.Expression> exprs, ErrorCont f,
  -        StatementCont s) {
  -      var cont = s;
  -      for (int i = exprs.length - 1; i >= 0; --i) {
  -        var nextCont = cont;
  -        cont = () {
  -          visitExpression(exprs[i])(f, (expr) {
  -            addStatement(expr);
  -            return nextCont();
  -          });
  -        };
  -      }
  -      return cont();
  -    }
  -
  -    translateDeclarations(List<ast.VariableDeclaration> decls,
  -        ErrorCont f, ExpressionListCont s) {
  -      var exprs = [];
  -      var seenAwait = false;
  -      var cont = (e) {
  -        exprs.add(e);
  -        return s(exprs);
  -      };
  -      for (var i = decls.length - 1; i >= 1; --i) {
  -        // Build the continuation for the i-1 initializer expression.
  -        var nextExpr = decls[i].initializer;
  -        if (nextExpr != null) {
  -          seenAwait = seenAwait || awaits.contains(nextExpr);
  -        }
  -        var nextCont = cont;
  -        if (nextExpr == null) {
  -          cont = (e) {
  -            exprs.add(e);
  -            nextCont(nullLiteral());
  -          };
  -        } else if (seenAwait) {
  -          cont = (e) {
  -            var value = addDeclaration('v', e);
  -            exprs.add(value);
  -            visitExpression(nextExpr)(f, nextCont);
  -          };
  -        } else {
  -          cont = (e) {
  -            exprs.add(e);
  -            visitExpression(nextExpr)(f, nextCont);
  -          };
  -        }
  -      }
  -      var expr = decls.first.initializer;
  -      if (expr == null) {
  -        return cont(nullLiteral());
  -      } else {
  -        return visitExpression(expr)(f, cont);
  -      }
  -    }
  -
  -    return (ErrorCont f, ReturnCont r, StatementCont s) {
  -      var breakName = newName('break');
  -      var continueName = newName('continue');
  -      var loopName = newName('loop');
  -
  -      var savedBlock = currentBlock;
  -      var breakBlock = currentBlock = emptyBlock();
  -      s();
  -
  -      var parameters;
  -      if (node.variables != null) {
  -        parameters = node.variables.variables.map((d) => d.name).toList();
  -      } else {
  -        parameters = <ast.SimpleIdentifier>[];
  -      }
  -
  -      var continueBlock = currentBlock = emptyBlock();
  -      trampoline() {
  -        addStatement(
  -            AstFactory.methodInvocation(
  -                AstFactory.functionExpressionInvocation(
  -                    AstFactory.identifier(identifier('Future'),
  -                                          identifier('wait')),
  -                    [AstFactory.listLiteral([])]),
  -                'then',
  -                [functionExpression (['_'],
  -                    AstFactory.functionExpressionInvocation(
  -                        identifier(loopName),
  -                        parameters))]));
  -      }
  -      if (node.updaters != null) {
  -        translateUpdaters(node.updaters, f, trampoline);
  -      } else {
  -        trampoline();
  -      }
  -
  -      var bodyBlock = currentBlock = emptyBlock();
  -      breakTargets.add(identifier(breakName));
  -      continueTargets.add(identifier(continueName));
  -      visit(node.body)(f, r, () {
  -        addStatement(
  -            AstFactory.functionExpressionInvocation(
                 identifier(continueName), [nullLiteral()]));
  -      });
  -      breakTargets.removeLast();
  -      continueTargets.removeLast();
  -
  -      var loopBlock = currentBlock = emptyBlock();
  -      addStatement(
  -          AstFactory.functionDeclarationStatement(null, null, continueName,
  -              functionExpression(['_'], continueBlock)));
  -      if (node.condition != null) {
  -        visitExpression(node.condition)(f, (expr) {
  -          addStatement(AstFactory.ifStatement2(
  -            expr,
  -            bodyBlock,
  -            block([AstFactory.functionExpressionInvocation(
  -                identifier(breakName), [nullLiteral()])])));
  -        });
  -      } else {
  -        addStatement(bodyBlock);
  -      }
  -
  -      currentBlock = savedBlock;
  -      addStatement(
  -          AstFactory.functionDeclarationStatement(null, null, breakName,
  -              functionExpression(['_'], breakBlock)));
  -      addStatement(
  -          AstFactory.functionDeclarationStatement(null, null, loopName,
  -              functionExpression(parameters.map((e) => e.name).toList(),
  -                  loopBlock)));
  -      if (node.variables != null) {
  -        assert(node.variables.variables.isNotEmpty);
  -        return translateDeclarations(node.variables.variables, f, (args) {
  -          assert(args.length == parameters.length);
  -          addStatement(AstFactory.functionExpressionInvocation(
  -              identifier(loopName), args));
  -        });
  -      } else if (node.initialization != null) {
  -        assert(parameters.isEmpty);
  -        return visitExpression(node.initialization)(f, (expr) {
  -          addStatement(expr);
  -          addStatement(AstFactory.functionExpressionInvocation(
  -              identifier(loopName), []));
  -        });
  -      } else {
  -        assert(parameters.isEmpty);
  -        return addStatement(AstFactory.functionExpressionInvocation(
  -            identifier(loopName), []));
  -      }
  -    };
  -  }
  -
  -  StatementTransformer visitForEachStatement(ast.ForEachStatement node) {
  +    });
  +    breakTargets.removeLast();
  +    continueTargets.removeLast();
  +
  +    currentBlock = savedBlock;
  +    addStatement(
  +        AstFactory.functionDeclarationStatement(null, null, breakName,
  +            functionExpression(['_'], breakBlock)));
  +    addStatement(
  +        AstFactory.functionDeclarationStatement(null, null, loopName,
  +            functionExpression(['_'], loopBlock)));
  +    addStatement(
  +        AstFactory.functionExpressionInvocation(
  +            identifier(loopName), [nullLiteral()]));
  +  };
  +
  +  visitEmptyStatement(ast.EmptyStatement node) => (f, r, s) {
  +    return s();
  +  };
  +
  +  visitExpressionStatement(ast.ExpressionStatement node) => (f, r, s) {
  +    return visit(node.expression)(f, (expr) {
  +      addStatement(expr);
  +      return s();
  +    });
  +  };
  +
  +  visitForEachStatement(ast.ForEachStatement node) {
       var stmt = emptyBlock();
       var it = newName('it');
       stmt.statements.add(
  
positive.code:   }
  }
  
  typedef void StatementCont();
  typedef void ReturnCont(ast.Expression expr);
  typedef void DeclarationListCont(List<ast.VariableDeclaration> decls);
  
  typedef void StatementTransformer(ErrorCont f, ReturnCont r, StatementCont s);
  typedef void DeclarationListTransformer(ErrorCont f, DeclarationListCont s);
  
  class AsyncTransformer extends ast.RecursiveAstVisitor<StatementTransformer> {
    final Set<ast.AstNode> awaits;
    AsyncExpressionTransformer expressionTransformer;
  
    ast.Block currentBlock;
  
    AsyncTransformer(this.awaits) {
      expressionTransformer = new AsyncExpressionTransformer(this);
    }
  
    visit(ast.AstNode node) => node.accept(this);
    ExpressionTransformer visitExpression(ast.Expression expr) {
      return expressionTransformer.visit(expr);
    }
  
    int counter = 0;
  
    // TODO: Safely generate fresh identifiers.
    String newName(String base) => '$base${counter++}';
  
    List<ast.Expression> breakTargets;
    List<ast.Expression> continueTargets;
  
    /// Insert a declaration with initial value [expr] in [currentBlock] and
    /// return the fresh name.
  
negative.code:     return fun;
    }
  
    // ---- CompilationUnit ----
    visitCompilationUnit(ast.CompilationUnit node) {
      // TODO(kmillikin): import 'dart:async' if necessary.
      return new ast.CompilationUnit(
          node.beginToken,
          node.scriptTag,
  