anchor.diff:      return stmt;
     }
   
  +  // The asynchronous loop `await for (T X in E) S1; S2;` is translated
  +  // with respect to an outer stream `outer` as:
  +  //
  +  // done() {
  +  //   outer.resume();
  +  //   [[S2]]
  +  // }
  +  // finally_(cont) {
  +  //   try {
  +  //     new Future.value(stream.cancel()).then(cont);
  +  //   } catch (ex, st) {
  +  //     ek(ex, st);
  +  //   }
  +  // }
  +  // catch_(ex, st) {
  +  //   finally_(() => ek(ex, st));
  +  // }
  +  // outer.pause();
  +  // var stream;
  +  // stream = [[E]].listen((v) {
  +  //     T X = v;
  +  //     [[S1]]
  +  // }, onError: catch_, onDone: done);
     visitForEachStatement(ast.ForEachStatement node) {
       if (node.awaitKeyword == null) {
         var stmt = _translateSynchronousForEach(node);
  
positive.code:     }
      return (rk, ek, sk) {
        return visit(node.iterator)(ek, (expr) {
          if (currentStream != null) {
            addStatement(make.methodInvocation(
                make.identifier(currentStream), 'pause', []));
          }
  
          var streamName = newName('s');
          var savedBlock = currentBlock;
          var doneBlock = currentBlock = make.emptyBlock();
          if (currentStream != null) {
            addStatement(make.methodInvocation(
                make.identifier(currentStream), 'resume', []));
          }
          sk();
  
          var listenBlock = currentBlock = make.emptyBlock();
          var parameter = newName('x');
  
negative.code:               node.loopVariable.type));
          }
  
          var savedBreakTargets = breakTargets;
          var savedContinueTargets = continueTargets;
          var savedStream = currentStream;
          breakTargets =
              breakTargets.map(_finallyBreakTarget(finallyName)).toList();
          continueTargets =
              continueTargets.map(_finallyContinueTarget(finallyName)).toList();
          currentStream = streamName;
          visit(node.body)((v) {
            v = addTempDeclaration(v);
            var savedBlock = currentBlock;
            var returnBlock = currentBlock = make.emptyBlock();
            rk(v);
            currentBlock = savedBlock;
            addStatement(make.functionInvocation(finallyName,
                [make.functionExpression([], returnBlock)]));
          }, new NamedErrorContinuation(catchName), () {});
  
  
          breakTargets = savedBreakTargets;
          continueTargets = savedContinueTargets;
          currentStream = savedStream;
          currentBlock = savedBlock;
          addStatement(
              make.functionDeclarationStatement(doneName, [], doneBlock));
          addStatement(make.variableDeclarationStatement(
              scanner.Keyword.VAR, [make.variableDeclaration(streamName)]));
          addStatement(make.functionDeclarationStatement(finallyName,
              [finallyContName], finallyBlock));
          addStatement(make.functionDeclarationStatement(catchName,
              [exceptionName, stackTraceName], catchBlock));
          if (currentStream != null) {
            addStatement(make.methodInvocation(
                make.identifier(currentStream), 'pause', []));
          }
          addStatement(make.assignmentExpression(
              make.identifier(streamName),
              make.methodInvocation(expr, 'listen',
                  [make.functionExpression([parameter], listenBlock),
                   make.namedExpression('onError', make.identifier(catchName)),
                   make.namedExpression('onDone', make.identifier(doneName))])));
        });
      };
    }
  