Version 1.9.0-dev.10.1

svn merge -c 44227 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 44228 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 44237 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 44239 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 44242 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 44246 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 44247 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 44250 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@44252 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index 44cca00..2fdf505 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -1189,9 +1189,15 @@
           _updateEndOld = endOffsetOld;
           _updateEndNew = endOffsetNew;
           _updateDelta = newUnit.length - _oldUnit.length;
+          // A comment change.
+          if (firstPair.kind == _TokenDifferenceKind.COMMENT) {
+            bool success = _resolveComment(newUnit, firstPair);
+            logger.log('Comment change: $success');
+            return success;
+          }
           // A Dart documentation comment change.
           if (firstPair.kind == _TokenDifferenceKind.COMMENT_DOC) {
-            bool success = _resolveComment(_oldUnit, newUnit, firstPair);
+            bool success = _resolveCommentDoc(newUnit, firstPair);
             logger.log('Documentation comment resolved: $success');
             return success;
           }
@@ -1309,11 +1315,32 @@
   }
 
   /**
+   * Attempts to resolve a comment change.
+   * Returns `true` if success.
+   */
+  bool _resolveComment(CompilationUnit newUnit, _TokenPair firstPair) {
+    Token oldToken = firstPair.oldToken;
+    Token newToken = firstPair.newToken;
+    CommentToken newComments = newToken.precedingComments;
+    // update token references
+    _updateOffset = oldToken.offset - 1;
+    _shiftTokens(firstPair.oldToken);
+    _setPrecedingComments(oldToken, newComments);
+    // update elements
+    IncrementalResolver incrementalResolver = new IncrementalResolver(
+        _unitElement, _updateOffset, _updateEndOld, _updateEndNew);
+    incrementalResolver._updateElementNameOffsets();
+    incrementalResolver._shiftEntryErrors();
+    _updateEntry();
+    // OK
+    return true;
+  }
+
+  /**
    * Attempts to resolve a documentation comment change.
    * Returns `true` if success.
    */
-  bool _resolveComment(
-      CompilationUnit oldUnit, CompilationUnit newUnit, _TokenPair firstPair) {
+  bool _resolveCommentDoc(CompilationUnit newUnit, _TokenPair firstPair) {
     Token oldToken = firstPair.oldToken;
     Token newToken = firstPair.newToken;
     CommentToken oldComments = oldToken.precedingComments;
@@ -1324,7 +1351,7 @@
     // find nodes
     int offset = oldComments.offset;
     logger.log('offset: $offset');
-    Comment oldComment = _findNodeCovering(oldUnit, offset, offset);
+    Comment oldComment = _findNodeCovering(_oldUnit, offset, offset);
     Comment newComment = _findNodeCovering(newUnit, offset, offset);
     logger.log('oldComment.beginToken: ${oldComment.beginToken}');
     logger.log('newComment.beginToken: ${newComment.beginToken}');
@@ -1355,6 +1382,40 @@
     return token;
   }
 
+  /**
+   * Set the given [comment] as a "precedingComments" for [token].
+   */
+  void _setPrecedingComments(Token token, CommentToken comment) {
+    if (token is BeginTokenWithComment) {
+      token.precedingComments = comment;
+    } else if (token is KeywordTokenWithComment) {
+      token.precedingComments = comment;
+    } else if (token is KeywordToken) {
+      KeywordTokenWithComment newToken =
+          new KeywordTokenWithComment(token.keyword, token.offset, comment);
+      token.previous.setNext(newToken);
+      newToken.setNext(token.next);
+      if (_oldUnit.beginToken == token) {
+        _oldUnit.beginToken = newToken;
+      }
+    } else if (token is StringTokenWithComment) {
+      token.precedingComments = comment;
+    } else if (token is StringToken) {
+      StringTokenWithComment newToken = new StringTokenWithComment(
+          token.type, token.value(), token.offset, comment);
+      token.previous.setNext(newToken);
+      newToken.setNext(token.next);
+      if (_oldUnit.beginToken == token) {
+        _oldUnit.beginToken = newToken;
+      }
+    } else if (token is TokenWithComment) {
+      token.precedingComments = comment;
+    } else {
+      Type parentType = token != null ? token.runtimeType : null;
+      throw new AnalysisException('Uknown parent token type: $parentType');
+    }
+  }
+
   void _shiftTokens(Token token) {
     while (token != null) {
       if (token.offset > _updateOffset) {
@@ -1518,24 +1579,6 @@
     }
     return count;
   }
-
-  /**
-   * Set the given [comment] as a "precedingComments" for [parent].
-   */
-  static void _setPrecedingComments(Token parent, CommentToken comment) {
-    if (parent is BeginTokenWithComment) {
-      parent.precedingComments = comment;
-    } else if (parent is KeywordTokenWithComment) {
-      parent.precedingComments = comment;
-    } else if (parent is StringTokenWithComment) {
-      parent.precedingComments = comment;
-    } else if (parent is TokenWithComment) {
-      parent.precedingComments = comment;
-    } else {
-      Type parentType = parent != null ? parent.runtimeType : null;
-      throw new AnalysisException('Uknown parent token type: $parentType');
-    }
-  }
 }
 
 /**
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index 44a595c..c65b545 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -2843,6 +2843,55 @@
 ''');
   }
 
+  void test_endOfLineComment_header_add() {
+    _resolveUnit(r'''
+main() {
+  Object x;
+  x.foo();
+}
+''');
+    _updateAndValidate(r'''
+// 000
+main() {
+  Object x;
+  x.foo();
+}
+''');
+  }
+
+  void test_endOfLineComment_header_remove() {
+    _resolveUnit(r'''
+// 000
+main() {
+  Object x;
+  x.foo();
+}
+''');
+    _updateAndValidate(r'''
+main() {
+  Object x;
+  x.foo();
+}
+''');
+  }
+
+  void test_endOfLineComment_header_update() {
+    _resolveUnit(r'''
+// 000
+main() {
+  Object x;
+  x.foo();
+}
+''');
+    _updateAndValidate(r'''
+// 10
+main() {
+  Object x;
+  x.foo();
+}
+''');
+  }
+
   void test_endOfLineComment_localFunction_inTopLevelVariable() {
     _resolveUnit(r'''
 typedef int Binary(one, two, three);
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart
index 66d94ab..1490ada 100644
--- a/pkg/compiler/lib/src/js/rewrite_async.dart
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart
@@ -1770,14 +1770,33 @@
   }
 
   @override
-  js.Fun finishFunction(List<js.Parameter> params,
+  js.Fun finishFunction(List<js.Parameter> parameters,
                         js.Statement rewrittenBody,
                         js.VariableDeclarationList variableDeclarations) {
+    // Each iterator invocation on the iterable should work on its own copy of
+    // the parameters.
+    // TODO(sigurdm): We only need to do this copying for parameters that are mutated.
+    List<js.VariableInitialization> declarations =
+        new List<js.VariableInitialization>();
+    List<js.Parameter> renamedParameters = new List<js.Parameter>();
+    for (js.Parameter parameter in parameters) {
+      String name = parameter.name;
+      String renamedName = freshName(name);
+      renamedParameters.add(new js.Parameter(renamedName));
+      declarations.add(
+          new js.VariableInitialization(new js.VariableDeclaration(name),
+                                        new js.VariableUse(renamedName)));
+    }
+    js.VariableDeclarationList copyParameters =
+        new js.VariableDeclarationList(declarations);
     return js.js("""
-          function (#params) {
+          function (#renamedParameters) {
             if (#needsThis)
               var #self = this;
             return new #newIterable(function () {
+              if (#hasParameters) {
+                #copyParameters;
+              }
               #varDecl;
               return function #body(#errorCode, #result) {
                 if (#errorCode === #ERROR) {
@@ -1789,9 +1808,11 @@
             });
           }
           """, {
-            "params": params,
+            "renamedParameters": renamedParameters,
             "needsThis": analysis.hasThis,
             "helperBody": rewrittenBody,
+            "hasParameters": parameters.isNotEmpty,
+            "copyParameters": copyParameters,
             "varDecl": variableDeclarations,
             "errorCode": errorCodeName,
             "newIterable": newIterable,
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 7fd5622..e57d0a9 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -279,16 +279,16 @@
 // Class which describes an inlined finally block which is used to generate
 // inlined code for the finally blocks when there is an exit from a try
 // block using 'return', 'break' or 'continue'.
-class Parser::TryBlocks : public ZoneAllocated {
+class Parser::TryStack : public ZoneAllocated {
  public:
-  TryBlocks(Block* try_block, TryBlocks* outer_try_block, intptr_t try_index)
+  TryStack(Block* try_block, TryStack* outer_try, intptr_t try_index)
       : try_block_(try_block),
         inlined_finally_nodes_(),
-        outer_try_block_(outer_try_block),
+        outer_try_(outer_try),
         try_index_(try_index),
         inside_catch_(false) { }
 
-  TryBlocks* outer_try_block() const { return outer_try_block_; }
+  TryStack* outer_try() const { return outer_try_; }
   Block* try_block() const { return try_block_; }
   intptr_t try_index() const { return try_index_; }
   bool inside_catch() const { return inside_catch_; }
@@ -305,15 +305,15 @@
  private:
   Block* try_block_;
   GrowableArray<AstNode*> inlined_finally_nodes_;
-  TryBlocks* outer_try_block_;
+  TryStack* outer_try_;
   const intptr_t try_index_;
   bool inside_catch_;
 
-  DISALLOW_COPY_AND_ASSIGN(TryBlocks);
+  DISALLOW_COPY_AND_ASSIGN(TryStack);
 };
 
 
-void Parser::TryBlocks::AddNodeForFinallyInlining(AstNode* node) {
+void Parser::TryStack::AddNodeForFinallyInlining(AstNode* node) {
   inlined_finally_nodes_.Add(node);
 }
 
@@ -335,7 +335,7 @@
       literal_token_(LiteralToken::Handle(zone())),
       current_class_(Class::Handle(zone())),
       library_(Library::Handle(zone(), library.raw())),
-      try_blocks_list_(NULL),
+      try_stack_(NULL),
       last_used_try_index_(0),
       unregister_pending_function_(false),
       async_temp_scope_(NULL),
@@ -368,7 +368,7 @@
       library_(Library::Handle(zone(), Class::Handle(
           zone(),
           parsed_function->function().origin()).library())),
-      try_blocks_list_(NULL),
+      try_stack_(NULL),
       last_used_try_index_(0),
       unregister_pending_function_(false),
       async_temp_scope_(NULL),
@@ -2153,6 +2153,7 @@
 void Parser::GenerateSuperConstructorCall(const Class& cls,
                                           intptr_t supercall_pos,
                                           LocalVariable* receiver,
+                                          AstNode* phase_parameter,
                                           ArgumentListNode* forwarding_args) {
   const Class& super_class = Class::Handle(Z, cls.SuperClass());
   // Omit the implicit super() if there is no super class (i.e.
@@ -2171,9 +2172,6 @@
   AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver);
   arguments->Add(implicit_argument);
   // Implicit construction phase parameter is second argument.
-  AstNode* phase_parameter =
-      new LiteralNode(supercall_pos,
-                      Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseAll)));
   arguments->Add(phase_parameter);
 
   // If this is a super call in a forwarding constructor, add the user-
@@ -2564,7 +2562,10 @@
   if (!super_init_seen) {
     // Generate implicit super() if we haven't seen an explicit super call
     // or constructor redirection.
-    GenerateSuperConstructorCall(cls, TokenPos(), receiver, NULL);
+    AstNode* phase_parameter = new LiteralNode(
+        TokenPos(), Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseAll)));
+    GenerateSuperConstructorCall(
+        cls, TokenPos(), receiver, phase_parameter, NULL);
   }
   CheckFieldsInitialized(cls);
 }
@@ -2686,10 +2687,12 @@
     }
   }
 
-  GenerateSuperConstructorCall(current_class(),
-                               Scanner::kNoSourcePos,
-                               receiver,
-                               forwarding_args);
+  GenerateSuperConstructorCall(
+      current_class(),
+      Scanner::kNoSourcePos,
+      receiver,
+      new LoadLocalNode(Scanner::kNoSourcePos, phase_parameter),
+      forwarding_args);
   CheckFieldsInitialized(current_class());
 
   // Empty constructor body.
@@ -5979,8 +5982,8 @@
   TRACE_PARSER("CloseAsyncGeneratorTryBlock");
   // The generated try-catch-finally that wraps the async generator function
   // body is the outermost try statement.
-  ASSERT(try_blocks_list_ != NULL);
-  ASSERT(try_blocks_list_->outer_try_block() == NULL);
+  ASSERT(try_stack_ != NULL);
+  ASSERT(try_stack_->outer_try() == NULL);
   // We only get here when parsing an async generator body.
   ASSERT(innermost_function().IsAsyncGenClosure());
 
@@ -5989,7 +5992,7 @@
   // The try-block (closure body code) has been parsed. We are now
   // generating the code for the catch block.
   LocalScope* try_scope = current_block_->scope;
-  try_blocks_list_->enter_catch();
+  try_stack_->enter_catch();
   OpenBlock();  // Catch handler list.
   OpenBlock();  // Catch block.
 
@@ -6070,8 +6073,8 @@
   current_block_->statements->Add(catch_block);
   SequenceNode* catch_handler_list = CloseBlock();
 
-  TryBlocks* try_block = PopTryBlock();
-  ASSERT(try_blocks_list_ == NULL);  // We popped the outermost try block.
+  TryStack* try_statement = PopTry();
+  ASSERT(try_stack_ == NULL);  // We popped the outermost try block.
 
   // Finally block: closing the stream and returning. (Note: the return
   // is necessary otherwise the back-end will append a rethrow of the
@@ -6095,7 +6098,7 @@
     current_block_->statements->Add(return_node);
 
     finally_clause = CloseBlock();
-    AstNode* node_to_inline = try_block->GetNodeToInlineFinally(node_index);
+    AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index);
     if (node_to_inline != NULL) {
       InlinedFinallyNode* node =
           new(Z) InlinedFinallyNode(try_end_pos,
@@ -6125,7 +6128,7 @@
       AllocateTryIndex(),
       true);
 
-  const intptr_t try_index = try_block->try_index();
+  const intptr_t try_index = try_statement->try_index();
 
   AstNode* try_catch_node =
       new(Z) TryCatchNode(Scanner::kNoSourcePos,
@@ -6141,12 +6144,12 @@
 
 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) {
   // This is the outermost try-catch of the function.
-  ASSERT(try_blocks_list_ != NULL);
-  ASSERT(try_blocks_list_->outer_try_block() == NULL);
+  ASSERT(try_stack_ != NULL);
+  ASSERT(try_stack_->outer_try() == NULL);
   ASSERT(innermost_function().IsAsyncClosure());
   LocalScope* try_scope = current_block_->scope;
 
-  try_blocks_list_->enter_catch();
+  try_stack_->enter_catch();
 
   OpenBlock();  // Catch handler list.
   OpenBlock();  // Catch block.
@@ -6231,8 +6234,8 @@
   handler_types.SetLength(0);
   handler_types.Add(*exception_param.type);
 
-  TryBlocks* inner_try_block = PopTryBlock();
-  const intptr_t try_index = inner_try_block->try_index();
+  TryStack* try_statement = PopTry();
+  const intptr_t try_index = try_statement->try_index();
 
   CatchClauseNode* catch_clause = new (Z) CatchClauseNode(
       Scanner::kNoSourcePos,
@@ -6277,8 +6280,8 @@
   // Open the try block.
   OpenBlock();
   // This is the outermost try-catch in the function.
-  ASSERT(try_blocks_list_ == NULL);
-  PushTryBlock(current_block_);
+  ASSERT(try_stack_ == NULL);
+  PushTry(current_block_);
 
   SetupSavedTryContext(context_var);
 }
@@ -8150,20 +8153,18 @@
 
 // If the await or yield being parsed is in a try block, the continuation code
 // needs to restore the corresponding stack-based variable :saved_try_ctx_var,
-// and possibly the stack-based variable :saved_try_ctx_var of the outer try
-// block.
+// and the stack-based variable :saved_try_ctx_var of the outer try block.
 // The inner :saved_try_ctx_var is used by a finally clause handling an
-// exception thrown by the continuation code in a catch clause. If no finally
-// clause exists, the catch or finally clause of the outer try block, if any,
-// uses the outer :saved_try_ctx_var to handle the exception.
+// exception thrown by the continuation code in a try block or catch block.
+// If no finally clause exists, the catch or finally clause of the outer try
+// block, if any, uses the outer :saved_try_ctx_var to handle the exception.
 //
-// * Try blocks: Set the context variable for this try block.
-// * Catch blocks: Set the context variable for this try block and for any outer
-//                 try block (if existent).
-// * Finally blocks: Set the context variable for any outer try block (if
-//                   existent). Note that this try block is popped before
-//                   parsing the finally clause, so the outer try block (if
-//                   existent) is at the top of the try block list.
+// * Try blocks and catch blocks:
+//     Set the context variable for this try block and for the outer try block.
+// * Finally blocks:
+//     Set the context variable for the outer try block. Note that the try
+//     declaring the finally is popped before parsing the finally clause, so the
+//     outer try block is at the top of the try block list.
 //
 // TODO(regis): Could we return the variables instead of their containing
 // scopes? Check if they are already setup at this point.
@@ -8175,20 +8176,21 @@
   *try_index = CatchClauseNode::kInvalidTryIndex;
   *outer_try_scope = NULL;
   *outer_try_index = CatchClauseNode::kInvalidTryIndex;
-  if (try_blocks_list_ != NULL) {
-    LocalScope* scope = try_blocks_list_->try_block()->scope;
+  if (try_stack_ != NULL) {
+    LocalScope* scope = try_stack_->try_block()->scope;
     const int current_function_level = current_block_->scope->function_level();
     if (scope->function_level() == current_function_level) {
       // The block declaring :saved_try_ctx_var variable is the parent of the
       // pushed try block.
       *try_scope = scope->parent();
-      *try_index = try_blocks_list_->try_index();
-      if (try_blocks_list_->inside_catch() &&
-          (try_blocks_list_->outer_try_block() != NULL)) {
-        scope = try_blocks_list_->outer_try_block()->try_block()->scope;
+      *try_index = try_stack_->try_index();
+      if (try_stack_->outer_try() != NULL) {
+        // TODO(regis): Collecting the outer try scope is not necessary if we
+        // are in a finally block. Add support for try_stack_->inside_finally().
+        scope = try_stack_->outer_try()->try_block()->scope;
         if (scope->function_level() == current_function_level) {
           *outer_try_scope = scope->parent();
-          *outer_try_index = try_blocks_list_->outer_try_block()->try_index();
+          *outer_try_index = try_stack_->outer_try()->try_index();
         }
       }
     }
@@ -8703,12 +8705,12 @@
   // outer try block (if it exists).  The current try block has already been
   // removed from the stack of try blocks.
   if (is_async) {
-    if (try_blocks_list_ != NULL) {
-      LocalScope* scope = try_blocks_list_->try_block()->scope;
+    if (try_stack_ != NULL) {
+      LocalScope* scope = try_stack_->try_block()->scope;
       if (scope->function_level() == current_block_->scope->function_level()) {
         current_block_->statements->Add(
             AwaitTransformer::RestoreSavedTryContext(
-                Z, scope->parent(), try_blocks_list_->try_index()));
+                Z, scope->parent(), try_stack_->try_index()));
       }
     }
     // We need to save the exception variables as in catch clauses, whether
@@ -8729,18 +8731,16 @@
 }
 
 
-void Parser::PushTryBlock(Block* try_block) {
+void Parser::PushTry(Block* try_block) {
   intptr_t try_index = AllocateTryIndex();
-  TryBlocks* block = new(Z) TryBlocks(
-      try_block, try_blocks_list_, try_index);
-  try_blocks_list_ = block;
+  try_stack_ = new(Z) TryStack(try_block, try_stack_, try_index);
 }
 
 
-Parser::TryBlocks* Parser::PopTryBlock() {
-  TryBlocks* innermost_try_block = try_blocks_list_;
-  try_blocks_list_ = try_blocks_list_->outer_try_block();
-  return innermost_try_block;
+Parser::TryStack* Parser::PopTry() {
+  TryStack* innermost_try = try_stack_;
+  try_stack_ = try_stack_->outer_try();
+  return innermost_try;
 }
 
 
@@ -8749,7 +8749,7 @@
     return;
   }
   ASSERT(node->IsReturnNode() || node->IsJumpNode());
-  TryBlocks* iterator = try_blocks_list_;
+  TryStack* iterator = try_stack_;
   while (iterator != NULL) {
     // For continue and break node check if the target label is in scope.
     if (node->IsJumpNode()) {
@@ -8766,7 +8766,7 @@
       }
     }
     iterator->AddNodeForFinallyInlining(node);
-    iterator = iterator->outer_try_block();
+    iterator = iterator->outer_try();
   }
 }
 
@@ -8963,9 +8963,9 @@
   // In case of async closures, restore :saved_try_context_var before executing
   // the catch clauses.
   if (is_async && (current != NULL)) {
-    ASSERT(try_blocks_list_ != NULL);
+    ASSERT(try_stack_ != NULL);
     SequenceNode* async_code = new(Z) SequenceNode(handler_pos, NULL);
-    const TryBlocks* try_block = try_blocks_list_->outer_try_block();
+    const TryStack* try_block = try_stack_->outer_try();
     if (try_block != NULL) {
       LocalScope* scope = try_block->try_block()->scope;
       if (scope->function_level() ==
@@ -9091,6 +9091,15 @@
 
 AstNode* Parser::ParseTryStatement(String* label_name) {
   TRACE_PARSER("ParseTryStatement");
+
+  const intptr_t try_pos = TokenPos();
+  SourceLabel* try_label = NULL;
+  if (label_name != NULL) {
+    try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement);
+    OpenBlock();
+    current_block_->scope->AddLabel(try_label);
+  }
+
   const bool is_async = innermost_function().IsAsyncClosure() ||
                         innermost_function().IsAsyncFunction() ||
                         innermost_function().IsSyncGenClosure() ||
@@ -9110,19 +9119,11 @@
                           &saved_exception_var,
                           &saved_stack_trace_var);
 
-  const intptr_t try_pos = TokenPos();
   ConsumeToken();  // Consume the 'try'.
 
-  SourceLabel* try_label = NULL;
-  if (label_name != NULL) {
-    try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement);
-    OpenBlock();
-    current_block_->scope->AddLabel(try_label);
-  }
-
   // Now parse the 'try' block.
   OpenBlock();
-  PushTryBlock(current_block_);
+  PushTry(current_block_);
   ExpectToken(Token::kLBRACE);
 
   if (is_async) {
@@ -9139,7 +9140,7 @@
   }
 
   // Now parse the 'catch' blocks if any.
-  try_blocks_list_->enter_catch();
+  try_stack_->enter_catch();
   const intptr_t handler_pos = TokenPos();
   const GrowableObjectArray& handler_types =
       GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
@@ -9154,12 +9155,11 @@
                         handler_types,
                         &needs_stack_trace);
 
-  TryBlocks* inner_try_block = PopTryBlock();
-  const intptr_t try_index = inner_try_block->try_index();
-  TryBlocks* outer_try_block = try_blocks_list_;
-  const intptr_t outer_try_index = (outer_try_block != NULL)
-      ? outer_try_block->try_index()
-      : CatchClauseNode::kInvalidTryIndex;
+  TryStack* try_statement = PopTry();
+  const intptr_t try_index = try_statement->try_index();
+  TryStack* outer_try = try_stack_;
+  const intptr_t outer_try_index = (outer_try != NULL) ?
+      outer_try->try_index() : CatchClauseNode::kInvalidTryIndex;
 
   // Finally parse the 'finally' block.
   SequenceNode* finally_block = NULL;
@@ -9168,8 +9168,7 @@
     const intptr_t finally_pos = TokenPos();
     // Add the finally block to the exit points recorded so far.
     intptr_t node_index = 0;
-    AstNode* node_to_inline =
-        inner_try_block->GetNodeToInlineFinally(node_index);
+    AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index);
     while (node_to_inline != NULL) {
       finally_block = ParseFinallyBlock(
           is_async,
@@ -9183,7 +9182,7 @@
                                                            outer_try_index);
       AddFinallyBlockToNode(is_async, node_to_inline, node);
       node_index += 1;
-      node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index);
+      node_to_inline = try_statement->GetNodeToInlineFinally(node_index);
       tokens_iterator_.SetCurrentPosition(finally_pos);
     }
     finally_block = ParseFinallyBlock(
@@ -9529,7 +9528,7 @@
     ConsumeToken();
     ExpectSemicolon();
     // Check if it is ok to do a rethrow.
-    if ((try_blocks_list_ == NULL) || !try_blocks_list_->inside_catch()) {
+    if ((try_stack_ == NULL) || !try_stack_->inside_catch()) {
       ReportError(statement_pos, "rethrow of an exception is not valid here");
     }
 
@@ -9537,7 +9536,7 @@
     // instead of :exception_var and :stack_trace_var.
     // These variables are bound in the block containing the try.
     // Look in the try scope directly.
-    LocalScope* scope = try_blocks_list_->try_block()->scope->parent();
+    LocalScope* scope = try_stack_->try_block()->scope->parent();
     ASSERT(scope != NULL);
     LocalVariable* excp_var;
     LocalVariable* trace_var;
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index d72d655..0e3d694 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -223,7 +223,7 @@
   friend class EffectGraphVisitor;  // For BuildNoSuchMethodArguments.
 
   struct Block;
-  class TryBlocks;
+  class TryStack;
 
   Parser(const Script& script, const Library& library, intptr_t token_pos);
   Parser(const Script& script, ParsedFunction* function, intptr_t token_pos);
@@ -465,6 +465,7 @@
   void GenerateSuperConstructorCall(const Class& cls,
                                     intptr_t supercall_pos,
                                     LocalVariable* receiver,
+                                    AstNode* phase_parameter,
                                     ArgumentListNode* forwarding_args);
   AstNode* ParseSuperInitializer(const Class& cls, LocalVariable* receiver);
   AstNode* ParseInitializer(const Class& cls,
@@ -619,10 +620,10 @@
                                   LocalVariable* stack_trace_var,
                                   LocalVariable* rethrow_exception_var,
                                   LocalVariable* rethrow_stack_trace_var);
-  // Adds try block to the list of try blocks seen so far.
-  void PushTryBlock(Block* try_block);
-  // Pops the inner most try block from the list.
-  TryBlocks* PopTryBlock();
+  // Push try block onto the stack of try blocks in scope.
+  void PushTry(Block* try_block);
+  // Pop the inner most try block from the stack.
+  TryStack* PopTry();
   // Collect try block scopes and indices if await or yield is in try block.
   void CheckAsyncOpInTryBlock(LocalScope** try_scope,
                               int16_t* try_index,
@@ -839,10 +840,10 @@
   // defined, or the library of a mixin class where the function originates.
   Library& library_;
 
-  // List of try blocks seen so far, this is used to generate inlined finally
+  // Stack of try blocks in scope, this is used to generate inlined finally
   // code at all points in the try block where an exit from the block is
   // done using 'return', 'break' or 'continue' statements.
-  TryBlocks* try_blocks_list_;
+  TryStack* try_stack_;
 
   // Each try in this function gets its own try index.
   int16_t AllocateTryIndex();
diff --git a/tests/language/async_break_in_finally_test.dart b/tests/language/async_break_in_finally_test.dart
new file mode 100644
index 0000000..4ac9994
--- /dev/null
+++ b/tests/language/async_break_in_finally_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+then43() async {
+  label: try {
+    return await 42;
+  } finally {
+    break label;
+  }
+  return await 43;
+}
+
+then42() async {
+  label: try {
+    return await 42;
+  } finally {
+  }
+  return await 43;
+}
+
+now43() {
+  label: try {
+    return 42;
+  } finally {
+    break label;
+  }
+  return 43;
+}
+
+now42() {
+  label: try {
+    return 42;
+  } finally {
+  }
+  return 43;
+}
+
+test() async {
+  Expect.equals(42, await then42());
+  Expect.equals(43, await then43());
+  Expect.equals(42, now42());
+  Expect.equals(43, now43());
+}
+
+main() {
+  asyncStart();
+  test().then((_) => asyncEnd());
+}
\ No newline at end of file
diff --git a/tests/language/constructor_with_mixin_test.dart b/tests/language/constructor_with_mixin_test.dart
new file mode 100644
index 0000000..0da9049
--- /dev/null
+++ b/tests/language/constructor_with_mixin_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test super constructor invocation with mixins.
+// Regression test for issue dartbug.com/22604
+
+import "package:expect/expect.dart";
+
+var a_count = 0;
+var b_count = 0;
+
+class A {
+  final int x;
+  A(int this.x) {
+    a_count++;
+  }
+}
+
+class I { }
+
+class B extends A with I {
+  int y;
+
+  B(int xx) : super(xx), y = 13 {
+    b_count++;
+  }
+}
+
+void main() {
+  var b = new B(17);
+  Expect.equals(1, a_count);
+  Expect.equals(1, b_count);
+}
+
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index f716bab..aead0c9 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -3,7 +3,6 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2js ]
-syncstar_yield_test/copyParameters: RuntimeError # Issue 22322
 sync_generator2_test/07: MissingCompileTimeError # Issue 22324
 sync_generator2_test/08: MissingCompileTimeError # Issue 22324
 sync_generator2_test/10: MissingCompileTimeError # Issue 22324
diff --git a/tests/language/regress_22579_test.dart b/tests/language/regress_22579_test.dart
new file mode 100644
index 0000000..76c8f42
--- /dev/null
+++ b/tests/language/regress_22579_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import "package:expect/expect.dart";
+
+foo() async {
+  try {
+    await 1;
+  } catch(e) {
+  }
+  throw "error";
+}
+
+main() async {
+  var error = "no error";
+  try {
+    await foo();
+  } catch (e) {
+    error = e;
+  }
+  Expect.equals("error", error);
+}
+
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index acc5091..3797f59 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -132,6 +132,7 @@
 mirrors/invocation_fuzz_test: RuntimeError # Issue 15566
 
 [ $compiler == dart2js && $runtime == jsshell ]
+async/timer_regress22626_test: RuntimeError # Non-zero timers not supported; Issue 7728.
 async/future_test: RuntimeError # Timer interface not supported; Issue 7728.
 async/slow_consumer2_test: RuntimeError # Timer interface not supported; Issue 7728.
 async/slow_consumer3_test: RuntimeError # Timer interface not supported; Issue 7728.
diff --git a/tools/VERSION b/tools/VERSION
index 8b10fa7..2f4c24a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
 MINOR 9
 PATCH 0
 PRERELEASE 10
-PRERELEASE_PATCH 0
+PRERELEASE_PATCH 1