Unify MapElement and CollectionElement

Change-Id: Ia1be138d656d07bdf4c11640b79044abbc798986
Reviewed-on: https://dart-review.googlesource.com/c/92762
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
index dddc8b4..0076909 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
@@ -415,20 +415,6 @@
   }
 
   @override
-  void visitCollectionForElement(CollectionForElement node) {
-    computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
-    super.visitCollectionForElement(node);
-  }
-
-  @override
-  void visitCollectionIfElement(CollectionIfElement node) {
-    computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD);
-    computer._addRegion_token(node.elseKeyword, HighlightRegionType.KEYWORD);
-    super.visitCollectionIfElement(node);
-  }
-
-  @override
   void visitConstructorDeclaration(ConstructorDeclaration node) {
     computer._addRegion_token(
         node.externalKeyword, HighlightRegionType.BUILT_IN);
@@ -509,6 +495,13 @@
   }
 
   @override
+  void visitForElement(ForElement node) {
+    computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
+    computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
+    super.visitForElement(node);
+  }
+
+  @override
   void visitForStatement(ForStatement node) {
     computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
     super.visitForStatement(node);
@@ -557,6 +550,13 @@
   }
 
   @override
+  void visitIfElement(IfElement node) {
+    computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD);
+    computer._addRegion_token(node.elseKeyword, HighlightRegionType.KEYWORD);
+    super.visitIfElement(node);
+  }
+
+  @override
   void visitIfStatement(IfStatement node) {
     computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD);
     computer._addRegion_token(node.elseKeyword, HighlightRegionType.KEYWORD);
@@ -622,20 +622,6 @@
   }
 
   @override
-  void visitMapForElement(MapForElement node) {
-    computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
-    super.visitMapForElement(node);
-  }
-
-  @override
-  void visitMapIfElement(MapIfElement node) {
-    computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD);
-    computer._addRegion_token(node.elseKeyword, HighlightRegionType.KEYWORD);
-    super.visitMapIfElement(node);
-  }
-
-  @override
   void visitMapLiteral(MapLiteral node) {
     computer._addRegion_node(node, HighlightRegionType.LITERAL_MAP);
     computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart b/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
index aaea61e..1f0326f 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
@@ -506,20 +506,6 @@
   }
 
   @override
-  void visitCollectionForElement(CollectionForElement node) {
-    computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
-    super.visitCollectionForElement(node);
-  }
-
-  @override
-  void visitCollectionIfElement(CollectionIfElement node) {
-    computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD);
-    computer._addRegion_token(node.elseKeyword, HighlightRegionType.KEYWORD);
-    super.visitCollectionIfElement(node);
-  }
-
-  @override
   void visitConstructorDeclaration(ConstructorDeclaration node) {
     computer._addRegion_token(
         node.externalKeyword, HighlightRegionType.BUILT_IN);
@@ -600,6 +586,13 @@
   }
 
   @override
+  void visitForElement(ForElement node) {
+    computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
+    computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
+    super.visitForElement(node);
+  }
+
+  @override
   void visitForStatement(ForStatement node) {
     computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
     super.visitForStatement(node);
@@ -648,6 +641,13 @@
   }
 
   @override
+  void visitIfElement(IfElement node) {
+    computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD);
+    computer._addRegion_token(node.elseKeyword, HighlightRegionType.KEYWORD);
+    super.visitIfElement(node);
+  }
+
+  @override
   void visitIfStatement(IfStatement node) {
     computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD);
     computer._addRegion_token(node.elseKeyword, HighlightRegionType.KEYWORD);
@@ -719,20 +719,6 @@
   }
 
   @override
-  void visitMapForElement(MapForElement node) {
-    computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
-    super.visitMapForElement(node);
-  }
-
-  @override
-  void visitMapIfElement(MapIfElement node) {
-    computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD);
-    computer._addRegion_token(node.elseKeyword, HighlightRegionType.KEYWORD);
-    super.visitMapIfElement(node);
-  }
-
-  @override
   void visitMapLiteral(MapLiteral node) {
     computer._addRegion_node(node, HighlightRegionType.LITERAL_MAP);
     computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index dcd8855..18b210c 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -3889,9 +3889,9 @@
   /// Return `true` if the [element] is sufficient to lexically make the
   /// enclosing literal a set literal rather than a map.
   bool _isUnambiguousElement(CollectionElement element) {
-    if (element is CollectionForElement) {
+    if (element is ForElement) {
       return _isUnambiguousElement(element.body);
-    } else if (element is CollectionIfElement) {
+    } else if (element is IfElement) {
       return _isUnambiguousElement(element.thenElement) ||
           _isUnambiguousElement(element.elseElement);
     } else if (element is Expression) {
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 946968c..3bf434e 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -453,10 +453,6 @@
 
   R visitClassTypeAlias(ClassTypeAlias node);
 
-  R visitCollectionForElement(CollectionForElement node);
-
-  R visitCollectionIfElement(CollectionIfElement node);
-
   R visitComment(Comment node);
 
   R visitCommentReference(CommentReference node);
@@ -511,6 +507,8 @@
 
   R visitForEachStatement(ForEachStatement node);
 
+  R visitForElement(ForElement node);
+
   R visitFormalParameterList(FormalParameterList node);
 
   R visitForPartsWithDeclarations(ForPartsWithDeclarations node);
@@ -539,6 +537,8 @@
 
   R visitHideCombinator(HideCombinator node);
 
+  R visitIfElement(IfElement node);
+
   R visitIfStatement(IfStatement node);
 
   R visitImplementsClause(ImplementsClause node);
@@ -569,10 +569,6 @@
 
   R visitListLiteral2(ListLiteral2 node);
 
-  R visitMapForElement(MapForElement node);
-
-  R visitMapIfElement(MapIfElement node);
-
   R visitMapLiteral(MapLiteral node);
 
   R visitMapLiteral2(MapLiteral2 node);
@@ -1098,36 +1094,18 @@
   void set withClause(WithClause withClause);
 }
 
-/// An element in a literal list or literal set.
+/// An element in a list, map or set literal.
 ///
 ///    collectionElement ::=
 ///        [Expression]
-///      | [IfElement<CollectionElement>]
-///      | [ForElement<CollectionElement>]
+///      | [IfElement]
+///      | [ForElement]
+///      | [MapLiteralEntry]
 ///      | [SpreadElement]
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class CollectionElement implements AstNode {}
 
-/// A for element in a literal list or literal set.
-///
-///    forElement ::=
-///        'await'? 'for' '(' [ForLoopParts] ')' [CollectionElement | MapElement]
-///
-/// Clients may not extend, implement or mix-in this class.
-abstract class CollectionForElement
-    implements CollectionElement, ForElement<CollectionElement> {}
-
-/// An if element in a literal list or literal set.
-///
-///    ifElement ::=
-///        'if' '(' [Expression] ')' [CollectionElement]
-///        ( 'else' [CollectionElement] )?
-///
-/// Clients may not extend, implement or mix-in this class.
-abstract class CollectionIfElement
-    implements CollectionElement, IfElement<CollectionElement> {}
-
 /// A combinator associated with an import or export directive.
 ///
 ///    combinator ::=
@@ -2321,13 +2299,13 @@
 /// The basic structure of a for element.
 ///
 /// Clients may not extend, implement or mix-in this class.
-abstract class ForElement<E> implements AstNode {
+abstract class ForElement implements CollectionElement {
   /// Return the token representing the 'await' keyword, or `null` if there was
   /// no 'await' keyword.
   Token get awaitKeyword;
 
   /// Return the body of the loop.
-  E get body;
+  CollectionElement get body;
 
   /// Return the token representing the 'for' keyword.
   Token get forKeyword;
@@ -3093,14 +3071,14 @@
 /// The basic structure of an if element.
 ///
 /// Clients may not extend, implement or mix-in this class.
-abstract class IfElement<E> implements AstNode {
+abstract class IfElement implements CollectionElement {
   /// Return the condition used to determine which of the statements is executed
   /// next.
   Expression get condition;
 
   /// Return the statement that is executed if the condition evaluates to
   /// `false`, or `null` if there is no else statement.
-  E get elseElement;
+  CollectionElement get elseElement;
 
   /// Return the token representing the 'else' keyword, or `null` if there is no
   /// else statement.
@@ -3117,7 +3095,7 @@
 
   /// Return the statement that is executed if the condition evaluates to
   /// `true`.
-  E get thenElement;
+  CollectionElement get thenElement;
 }
 
 /// An if statement.
@@ -3788,33 +3766,6 @@
 /// Clients may not extend, implement or mix-in this class.
 abstract class Literal implements Expression {}
 
-/// An element in a literal map.
-///
-///    mapElement ::=
-///        [Expression]
-///      | [IfElement<MapElement>]
-///      | [ForElement<MapElement>]
-///      | [SpreadElement]
-///
-/// Clients may not extend, implement or mix-in this class.
-abstract class MapElement implements AstNode {}
-
-/// A for element in a literal map.
-///
-///    forElement ::=
-///        'await'? 'for' '(' [ForLoopParts] ')' [CollectionElement | MapElement]
-///
-/// Clients may not extend, implement or mix-in this class.
-abstract class MapForElement implements ForElement<MapElement>, MapElement {}
-
-/// An if element in a map in a literal map.
-///
-///    ifElement ::=
-///        'if' '(' [Expression] ')' [MapElement] ( 'else' [MapElement] )?
-///
-/// Clients may not extend, implement or mix-in this class.
-abstract class MapIfElement implements IfElement<MapElement>, MapElement {}
-
 /// A literal map.
 ///
 ///    mapLiteral ::=
@@ -3856,7 +3807,7 @@
 /// Clients may not extend, implement or mix-in this class.
 abstract class MapLiteral2 implements TypedLiteral {
   /// Return the entries in the map.
-  NodeList<MapElement> get entries;
+  NodeList<CollectionElement> get entries;
 
   /// Return the left curly bracket.
   Token get leftBracket;
@@ -3877,7 +3828,7 @@
 ///        [Expression] ':' [Expression]
 ///
 /// Clients may not extend, implement or mix-in this class.
-abstract class MapLiteralEntry implements MapElement {
+abstract class MapLiteralEntry implements CollectionElement {
   /// Return the expression computing the key with which the value will be
   /// associated.
   Expression get key;
@@ -4924,7 +4875,7 @@
 ///        ( '...' | '...?' ) [Expression]
 ///
 /// Clients may not extend, implement or mix-in this class.
-abstract class SpreadElement implements CollectionElement, MapElement {
+abstract class SpreadElement implements CollectionElement {
   /// The expression used to compute the collection being spread.
   Expression get expression;
 
diff --git a/pkg/analyzer/lib/dart/ast/ast_factory.dart b/pkg/analyzer/lib/dart/ast/ast_factory.dart
index fee50cb..c888aac 100644
--- a/pkg/analyzer/lib/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/dart/ast/ast_factory.dart
@@ -185,31 +185,6 @@
       Token semicolon);
 
   /**
-   * Returns a newly created for element that can be part of a list or set
-   * literal.
-   */
-  CollectionForElement collectionForElement(
-      {Token awaitKeyword,
-      Token forKeyword,
-      Token leftParenthesis,
-      ForLoopParts forLoopParts,
-      Token rightParenthesis,
-      CollectionElement body});
-
-  /**
-   * Returns a newly created if element that can be part of a list or set
-   * literal.
-   */
-  CollectionIfElement collectionIfElement(
-      {Token ifKeyword,
-      Token leftParenthesis,
-      Expression condition,
-      Token rightParenthesis,
-      CollectionElement thenElement,
-      Token elseKeyword,
-      CollectionElement elseElement});
-
-  /**
    * Returns a newly created reference to a Dart element. The [newKeyword]
    * can be `null` if the reference is not to a constructor.
    */
@@ -543,6 +518,18 @@
       Statement body);
 
   /**
+   * Returns a newly created for element that can be part of a list, map or set
+   * literal.
+   */
+  ForElement forElement(
+      {Token awaitKeyword,
+      Token forKeyword,
+      Token leftParenthesis,
+      ForLoopParts forLoopParts,
+      Token rightParenthesis,
+      CollectionElement body});
+
+  /**
    * Returns a newly created parameter list. The list of [parameters] can be
    * `null` if there are no parameters. The [leftDelimiter] and [rightDelimiter]
    * can be `null` if there are no optional parameters.
@@ -720,6 +707,19 @@
       Token keyword, List<SimpleIdentifier> hiddenNames);
 
   /**
+   * Returns a newly created if element that can be part of a list, map or set
+   * literal.
+   */
+  IfElement ifElement(
+      {Token ifKeyword,
+      Token leftParenthesis,
+      Expression condition,
+      Token rightParenthesis,
+      CollectionElement thenElement,
+      Token elseKeyword,
+      CollectionElement elseElement});
+
+  /**
    * Returns a newly created if statement. The [elseKeyword] and
    * [elseStatement] can be `null` if there is no else clause.
    */
@@ -844,29 +844,6 @@
       Token rightBracket});
 
   /**
-   * Returns a newly created for element that can be part of a map literal.
-   */
-  MapForElement mapForElement(
-      {Token awaitKeyword,
-      Token forKeyword,
-      Token leftParenthesis,
-      ForLoopParts forLoopParts,
-      Token rightParenthesis,
-      MapElement body});
-
-  /**
-   * Returns a newly created if element that can be part of a map literal.
-   */
-  MapIfElement mapIfElement(
-      {Token ifKeyword,
-      Token leftParenthesis,
-      Expression condition,
-      Token rightParenthesis,
-      MapElement thenElement,
-      Token elseKeyword,
-      MapElement elseElement});
-
-  /**
    * Returns a newly created map literal. The [constKeyword] can be `null` if
    * the literal is not a constant. The [typeArguments] can be `null` if no type
    * arguments were declared. The [entries] can be `null` if the map is empty.
@@ -881,7 +858,7 @@
       {Token constKeyword,
       TypeArgumentList typeArguments,
       Token leftBracket,
-      List<MapElement> entries,
+      List<CollectionElement> entries,
       Token rightBracket});
 
   /**
diff --git a/pkg/analyzer/lib/dart/ast/visitor.dart b/pkg/analyzer/lib/dart/ast/visitor.dart
index e1c77f4..4c599e8 100644
--- a/pkg/analyzer/lib/dart/ast/visitor.dart
+++ b/pkg/analyzer/lib/dart/ast/visitor.dart
@@ -205,13 +205,7 @@
   @override
   R visitClassTypeAlias(ClassTypeAlias node) => visitTypeAlias(node);
 
-  @override
-  R visitCollectionForElement(CollectionForElement node) =>
-      visitForElement<CollectionElement>(node);
-
-  @override
-  R visitCollectionIfElement(CollectionIfElement node) =>
-      visitIfElement<CollectionElement>(node);
+  R visitCollectionElement(CollectionElement node) => visitNode(node);
 
   R visitCombinator(Combinator node) => visitNode(node);
 
@@ -287,7 +281,7 @@
   @override
   R visitExportDirective(ExportDirective node) => visitNamespaceDirective(node);
 
-  R visitExpression(Expression node) => visitNode(node);
+  R visitExpression(Expression node) => visitCollectionElement(node);
 
   @override
   R visitExpressionFunctionBody(ExpressionFunctionBody node) =>
@@ -319,7 +313,8 @@
   @override
   R visitForEachStatement(ForEachStatement node) => visitStatement(node);
 
-  R visitForElement<E>(ForElement<E> node) => visitNode(node);
+  @override
+  R visitForElement(ForElement node) => visitCollectionElement(node);
 
   R visitFormalParameter(FormalParameter node) => visitNode(node);
 
@@ -378,7 +373,8 @@
 
   R visitIdentifier(Identifier node) => visitExpression(node);
 
-  R visitIfElement<E>(IfElement<E> node) => visitNode(node);
+  @override
+  R visitIfElement(IfElement node) => visitCollectionElement(node);
 
   @override
   R visitIfStatement(IfStatement node) => visitStatement(node);
@@ -436,19 +432,13 @@
   R visitLiteral(Literal node) => visitExpression(node);
 
   @override
-  R visitMapForElement(MapForElement node) => visitForElement<MapElement>(node);
-
-  @override
-  R visitMapIfElement(MapIfElement node) => visitIfElement<MapElement>(node);
-
-  @override
   R visitMapLiteral(MapLiteral node) => visitTypedLiteral(node);
 
   @override
   R visitMapLiteral2(MapLiteral2 node) => visitTypedLiteral(node);
 
   @override
-  R visitMapLiteralEntry(MapLiteralEntry node) => visitNode(node);
+  R visitMapLiteralEntry(MapLiteralEntry node) => visitCollectionElement(node);
 
   @override
   R visitMethodDeclaration(MethodDeclaration node) => visitClassMember(node);
@@ -550,7 +540,7 @@
       visitStringLiteral(node);
 
   @override
-  R visitSpreadElement(SpreadElement node) => visitNode(node);
+  R visitSpreadElement(SpreadElement node) => visitCollectionElement(node);
 
   R visitStatement(Statement node) => visitNode(node);
 
@@ -752,18 +742,6 @@
   }
 
   @override
-  R visitCollectionForElement(CollectionForElement node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitCollectionIfElement(CollectionIfElement node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
   R visitComment(Comment node) {
     node.visitChildren(this);
     return null;
@@ -926,6 +904,12 @@
   }
 
   @override
+  R visitForElement(ForElement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R visitFormalParameterList(FormalParameterList node) {
     node.visitChildren(this);
     return null;
@@ -1010,6 +994,12 @@
   }
 
   @override
+  R visitIfElement(IfElement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R visitIfStatement(IfStatement node) {
     node.visitChildren(this);
     return null;
@@ -1100,18 +1090,6 @@
   }
 
   @override
-  R visitMapForElement(MapForElement node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitMapIfElement(MapIfElement node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
   R visitMapLiteral(MapLiteral node) {
     node.visitChildren(this);
     return null;
@@ -1474,12 +1452,6 @@
   R visitClassTypeAlias(ClassTypeAlias node) => null;
 
   @override
-  R visitCollectionForElement(CollectionForElement node) => null;
-
-  @override
-  R visitCollectionIfElement(CollectionIfElement node) => null;
-
-  @override
   R visitComment(Comment node) => null;
 
   @override
@@ -1561,6 +1533,9 @@
   R visitForEachStatement(ForEachStatement node) => null;
 
   @override
+  R visitForElement(ForElement node) => null;
+
+  @override
   R visitFormalParameterList(FormalParameterList node) => null;
 
   @override
@@ -1606,6 +1581,9 @@
   R visitHideCombinator(HideCombinator node) => null;
 
   @override
+  R visitIfElement(IfElement node) => null;
+
+  @override
   R visitIfStatement(IfStatement node) => null;
 
   @override
@@ -1651,12 +1629,6 @@
   R visitListLiteral2(ListLiteral2 node) => null;
 
   @override
-  R visitMapForElement(MapForElement node) => null;
-
-  @override
-  R visitMapIfElement(MapIfElement node) => null;
-
-  @override
   R visitMapLiteral(MapLiteral node) => null;
 
   @override
@@ -1872,12 +1844,6 @@
   R visitClassTypeAlias(ClassTypeAlias node) => _throw(node);
 
   @override
-  R visitCollectionForElement(CollectionForElement node) => _throw(node);
-
-  @override
-  R visitCollectionIfElement(CollectionIfElement node) => _throw(node);
-
-  @override
   R visitComment(Comment node) => _throw(node);
 
   @override
@@ -1962,6 +1928,9 @@
   R visitForEachStatement(ForEachStatement node) => _throw(node);
 
   @override
+  R visitForElement(ForElement node) => _throw(node);
+
+  @override
   R visitFormalParameterList(FormalParameterList node) => _throw(node);
 
   @override
@@ -2008,6 +1977,9 @@
   R visitHideCombinator(HideCombinator node) => _throw(node);
 
   @override
+  R visitIfElement(IfElement node) => _throw(node);
+
+  @override
   R visitIfStatement(IfStatement node) => _throw(node);
 
   @override
@@ -2054,12 +2026,6 @@
   R visitListLiteral2(ListLiteral2 node) => _throw(node);
 
   @override
-  R visitMapForElement(MapForElement node) => _throw(node);
-
-  @override
-  R visitMapIfElement(MapIfElement node) => _throw(node);
-
-  @override
   R visitMapLiteral(MapLiteral node) => _throw(node);
 
   @override
@@ -2378,22 +2344,6 @@
   }
 
   @override
-  T visitCollectionForElement(CollectionForElement node) {
-    stopwatch.start();
-    T result = _baseVisitor.visitCollectionForElement(node);
-    stopwatch.stop();
-    return result;
-  }
-
-  @override
-  T visitCollectionIfElement(CollectionIfElement node) {
-    stopwatch.start();
-    T result = _baseVisitor.visitCollectionIfElement(node);
-    stopwatch.stop();
-    return result;
-  }
-
-  @override
   T visitComment(Comment node) {
     stopwatch.start();
     T result = _baseVisitor.visitComment(node);
@@ -2610,6 +2560,14 @@
   }
 
   @override
+  T visitForElement(ForElement node) {
+    stopwatch.start();
+    T result = _baseVisitor.visitForElement(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T visitFormalParameterList(FormalParameterList node) {
     stopwatch.start();
     T result = _baseVisitor.visitFormalParameterList(node);
@@ -2722,6 +2680,14 @@
   }
 
   @override
+  T visitIfElement(IfElement node) {
+    stopwatch.start();
+    T result = _baseVisitor.visitIfElement(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T visitIfStatement(IfStatement node) {
     stopwatch.start();
     T result = _baseVisitor.visitIfStatement(node);
@@ -2842,22 +2808,6 @@
   }
 
   @override
-  T visitMapForElement(MapForElement node) {
-    stopwatch.start();
-    T result = _baseVisitor.visitMapForElement(node);
-    stopwatch.stop();
-    return result;
-  }
-
-  @override
-  T visitMapIfElement(MapIfElement node) {
-    stopwatch.start();
-    T result = _baseVisitor.visitMapIfElement(node);
-    stopwatch.stop();
-    return result;
-  }
-
-  @override
   T visitMapLiteral(MapLiteral node) {
     stopwatch.start();
     T result = _baseVisitor.visitMapLiteral(node);
@@ -3324,12 +3274,6 @@
   R visitClassTypeAlias(ClassTypeAlias node) => visitNode(node);
 
   @override
-  R visitCollectionForElement(CollectionForElement node) => visitNode(node);
-
-  @override
-  R visitCollectionIfElement(CollectionIfElement node) => visitNode(node);
-
-  @override
   R visitComment(Comment node) => visitNode(node);
 
   @override
@@ -3415,6 +3359,9 @@
   R visitForEachStatement(ForEachStatement node) => visitNode(node);
 
   @override
+  R visitForElement(ForElement node) => visitNode(node);
+
+  @override
   R visitFormalParameterList(FormalParameterList node) => visitNode(node);
 
   @override
@@ -3461,6 +3408,9 @@
   R visitHideCombinator(HideCombinator node) => visitNode(node);
 
   @override
+  R visitIfElement(IfElement node) => visitNode(node);
+
+  @override
   R visitIfStatement(IfStatement node) => visitNode(node);
 
   @override
@@ -3508,12 +3458,6 @@
   R visitListLiteral2(ListLiteral2 node) => visitNode(node);
 
   @override
-  R visitMapForElement(MapForElement node) => visitNode(node);
-
-  @override
-  R visitMapIfElement(MapIfElement node) => visitNode(node);
-
-  @override
   R visitMapLiteral(MapLiteral node) => visitNode(node);
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index d6abf5e..93bfdfd 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -2059,125 +2059,6 @@
 abstract class CollectionElementImpl extends AstNodeImpl
     implements CollectionElement {}
 
-class CollectionForElementImpl extends CollectionElementImpl
-    with ForMixin
-    implements CollectionForElement {
-  /**
-   * The body of the loop.
-   */
-  CollectionElementImpl _body;
-
-  /**
-   * Initialize a newly created for element.
-   */
-  CollectionForElementImpl(
-      Token awaitKeyword,
-      Token forKeyword,
-      Token leftParenthesis,
-      ForLoopPartsImpl forLoopParts,
-      Token rightParenthesis,
-      CollectionElementImpl body) {
-    this.awaitKeyword = awaitKeyword;
-    this.forKeyword = forKeyword;
-    this.leftParenthesis = leftParenthesis;
-    _forLoopParts = _becomeParentOf(forLoopParts);
-    this.rightParenthesis = rightParenthesis;
-    _body = _becomeParentOf(body);
-  }
-
-  @override
-  CollectionElement get body => _body;
-
-  void set body(CollectionElement statement) {
-    _body = _becomeParentOf(statement as CollectionElementImpl);
-  }
-
-  @override
-  Iterable<SyntacticEntity> get childEntities => new ChildEntities()
-    ..addAll(super.childEntities)
-    ..add(_body);
-
-  @override
-  Token get endToken => _body.endToken;
-
-  @override
-  E accept<E>(AstVisitor<E> visitor) => visitor.visitCollectionForElement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _forLoopParts?.accept(visitor);
-    _body?.accept(visitor);
-  }
-}
-
-class CollectionIfElementImpl extends CollectionElementImpl
-    with IfMixin
-    implements CollectionIfElement {
-  /**
-   * The element to be executed if the condition is `true`.
-   */
-  CollectionElementImpl _thenElement;
-
-  /**
-   * The element to be executed if the condition is `false`, or `null` if there
-   * is no such element.
-   */
-  CollectionElementImpl _elseElement;
-
-  /**
-   * Initialize a newly created for element.
-   */
-  CollectionIfElementImpl(
-      Token ifKeyword,
-      Token leftParenthesis,
-      ExpressionImpl condition,
-      Token rightParenthesis,
-      CollectionElementImpl thenElement,
-      Token elseKeyword,
-      CollectionElementImpl elseElement) {
-    this.ifKeyword = ifKeyword;
-    this.leftParenthesis = leftParenthesis;
-    _condition = _becomeParentOf(condition);
-    this.rightParenthesis = rightParenthesis;
-    _thenElement = _becomeParentOf(thenElement);
-    this.elseKeyword = elseKeyword;
-    _elseElement = _becomeParentOf(elseElement);
-  }
-
-  @override
-  Iterable<SyntacticEntity> get childEntities => new ChildEntities()
-    ..addAll(super.childEntities)
-    ..add(_thenElement)
-    ..add(_elseElement);
-
-  @override
-  CollectionElement get elseElement => _elseElement;
-
-  set elseElement(CollectionElement element) {
-    _elseElement = _becomeParentOf(element as CollectionElementImpl);
-  }
-
-  @override
-  Token get endToken => _elseElement?.endToken ?? _thenElement.endToken;
-
-  @override
-  CollectionElement get thenElement => _thenElement;
-
-  set thenElement(CollectionElement element) {
-    _thenElement = _becomeParentOf(element as CollectionElementImpl);
-  }
-
-  @override
-  E accept<E>(AstVisitor<E> visitor) => visitor.visitCollectionIfElement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _thenElement?.accept(visitor);
-    _elseElement?.accept(visitor);
-  }
-}
-
 /**
  * A combinator associated with an import or export directive.
  *
@@ -4963,6 +4844,57 @@
   }
 }
 
+class ForElementImpl extends CollectionElementImpl
+    with ForMixin
+    implements ForElement {
+  /**
+   * The body of the loop.
+   */
+  CollectionElementImpl _body;
+
+  /**
+   * Initialize a newly created for element.
+   */
+  ForElementImpl(
+      Token awaitKeyword,
+      Token forKeyword,
+      Token leftParenthesis,
+      ForLoopPartsImpl forLoopParts,
+      Token rightParenthesis,
+      CollectionElementImpl body) {
+    this.awaitKeyword = awaitKeyword;
+    this.forKeyword = forKeyword;
+    this.leftParenthesis = leftParenthesis;
+    _forLoopParts = _becomeParentOf(forLoopParts);
+    this.rightParenthesis = rightParenthesis;
+    _body = _becomeParentOf(body);
+  }
+
+  @override
+  CollectionElement get body => _body;
+
+  void set body(CollectionElement statement) {
+    _body = _becomeParentOf(statement as CollectionElementImpl);
+  }
+
+  @override
+  Iterable<SyntacticEntity> get childEntities => new ChildEntities()
+    ..addAll(super.childEntities)
+    ..add(_body);
+
+  @override
+  Token get endToken => _body.endToken;
+
+  @override
+  E accept<E>(AstVisitor<E> visitor) => visitor.visitForElement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _forLoopParts?.accept(visitor);
+    _body?.accept(visitor);
+  }
+}
+
 abstract class ForLoopPartsImpl extends AstNodeImpl implements ForLoopParts {}
 
 /**
@@ -6445,6 +6377,74 @@
   bool get isAssignable => true;
 }
 
+class IfElementImpl extends CollectionElementImpl
+    with IfMixin
+    implements IfElement {
+  /**
+   * The element to be executed if the condition is `true`.
+   */
+  CollectionElementImpl _thenElement;
+
+  /**
+   * The element to be executed if the condition is `false`, or `null` if there
+   * is no such element.
+   */
+  CollectionElementImpl _elseElement;
+
+  /**
+   * Initialize a newly created for element.
+   */
+  IfElementImpl(
+      Token ifKeyword,
+      Token leftParenthesis,
+      ExpressionImpl condition,
+      Token rightParenthesis,
+      CollectionElementImpl thenElement,
+      Token elseKeyword,
+      CollectionElementImpl elseElement) {
+    this.ifKeyword = ifKeyword;
+    this.leftParenthesis = leftParenthesis;
+    _condition = _becomeParentOf(condition);
+    this.rightParenthesis = rightParenthesis;
+    _thenElement = _becomeParentOf(thenElement);
+    this.elseKeyword = elseKeyword;
+    _elseElement = _becomeParentOf(elseElement);
+  }
+
+  @override
+  Iterable<SyntacticEntity> get childEntities => new ChildEntities()
+    ..addAll(super.childEntities)
+    ..add(_thenElement)
+    ..add(_elseElement);
+
+  @override
+  CollectionElement get elseElement => _elseElement;
+
+  set elseElement(CollectionElement element) {
+    _elseElement = _becomeParentOf(element as CollectionElementImpl);
+  }
+
+  @override
+  Token get endToken => _elseElement?.endToken ?? _thenElement.endToken;
+
+  @override
+  CollectionElement get thenElement => _thenElement;
+
+  set thenElement(CollectionElement element) {
+    _thenElement = _becomeParentOf(element as CollectionElementImpl);
+  }
+
+  @override
+  E accept<E>(AstVisitor<E> visitor) => visitor.visitIfElement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _thenElement?.accept(visitor);
+    _elseElement?.accept(visitor);
+  }
+}
+
 mixin IfMixin on AstNodeImpl {
   Token ifKeyword;
 
@@ -7985,127 +7985,6 @@
       new Set<VariableElement>();
 }
 
-abstract class MapElementImpl extends AstNodeImpl implements MapElement {}
-
-class MapForElementImpl extends MapElementImpl
-    with ForMixin
-    implements MapForElement {
-  /**
-   * The body of the loop.
-   */
-  MapElementImpl _body;
-
-  /**
-   * Initialize a newly created for element.
-   */
-  MapForElementImpl(
-      Token awaitKeyword,
-      Token forKeyword,
-      Token leftParenthesis,
-      ForLoopPartsImpl forLoopParts,
-      Token rightParenthesis,
-      MapElementImpl body) {
-    this.awaitKeyword = awaitKeyword;
-    this.forKeyword = forKeyword;
-    this.leftParenthesis = leftParenthesis;
-    _forLoopParts = _becomeParentOf(forLoopParts);
-    this.rightParenthesis = rightParenthesis;
-    _body = _becomeParentOf(body);
-  }
-
-  @override
-  MapElement get body => _body;
-
-  void set body(MapElement statement) {
-    _body = _becomeParentOf(statement as MapElementImpl);
-  }
-
-  @override
-  Iterable<SyntacticEntity> get childEntities => new ChildEntities()
-    ..addAll(super.childEntities)
-    ..add(_body);
-
-  @override
-  Token get endToken => _body.endToken;
-
-  @override
-  E accept<E>(AstVisitor<E> visitor) => visitor.visitMapForElement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _forLoopParts?.accept(visitor);
-    _body?.accept(visitor);
-  }
-}
-
-class MapIfElementImpl extends MapElementImpl
-    with IfMixin
-    implements MapIfElement {
-  /**
-   * The element to be executed if the condition is `true`.
-   */
-  MapElementImpl _thenElement;
-
-  /**
-   * The element to be executed if the condition is `false`, or `null` if there
-   * is no such element.
-   */
-  MapElementImpl _elseElement;
-
-  /**
-   * Initialize a newly created for element.
-   */
-  MapIfElementImpl(
-      Token ifKeyword,
-      Token leftParenthesis,
-      ExpressionImpl condition,
-      Token rightParenthesis,
-      MapElementImpl thenElement,
-      Token elseKeyword,
-      MapElementImpl elseElement) {
-    this.ifKeyword = ifKeyword;
-    this.leftParenthesis = leftParenthesis;
-    _condition = _becomeParentOf(condition);
-    this.rightParenthesis = rightParenthesis;
-    _thenElement = _becomeParentOf(thenElement);
-    this.elseKeyword = elseKeyword;
-    _elseElement = _becomeParentOf(elseElement);
-  }
-
-  @override
-  Iterable<SyntacticEntity> get childEntities => new ChildEntities()
-    ..addAll(super.childEntities)
-    ..add(_thenElement)
-    ..add(_elseElement);
-
-  @override
-  MapElement get elseElement => _elseElement;
-
-  set elseElement(MapElement element) {
-    _elseElement = _becomeParentOf(element as MapElementImpl);
-  }
-
-  @override
-  Token get endToken => _elseElement?.endToken ?? _thenElement.endToken;
-
-  @override
-  MapElement get thenElement => _thenElement;
-
-  set thenElement(MapElement element) {
-    _thenElement = _becomeParentOf(element as MapElementImpl);
-  }
-
-  @override
-  E accept<E>(AstVisitor<E> visitor) => visitor.visitMapIfElement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _thenElement?.accept(visitor);
-    _elseElement?.accept(visitor);
-  }
-}
-
 /**
  * A literal map.
  *
@@ -8124,7 +8003,7 @@
   /**
    * The entries in the map.
    */
-  NodeList<MapElement> _entries;
+  NodeList<CollectionElement> _entries;
 
   @override
   Token rightBracket;
@@ -8135,9 +8014,9 @@
    * arguments were declared. The [entries] can be `null` if the map is empty.
    */
   MapLiteral2Impl(Token constKeyword, TypeArgumentListImpl typeArguments,
-      this.leftBracket, List<MapElement> entries, this.rightBracket)
+      this.leftBracket, List<CollectionElement> entries, this.rightBracket)
       : super(constKeyword, typeArguments) {
-    _entries = new NodeListImpl<MapElement>(this, entries);
+    _entries = new NodeListImpl<CollectionElement>(this, entries);
   }
 
   @override
@@ -8163,7 +8042,7 @@
   Token get endToken => rightBracket;
 
   @override
-  NodeList<MapElement> get entries => _entries;
+  NodeList<CollectionElement> get entries => _entries;
 
   @override
   E accept<E>(AstVisitor<E> visitor) => visitor.visitMapLiteral2(this);
@@ -8181,7 +8060,8 @@
  *    mapLiteralEntry ::=
  *        [Expression] ':' [Expression]
  */
-class MapLiteralEntryImpl extends MapElementImpl implements MapLiteralEntry {
+class MapLiteralEntryImpl extends CollectionElementImpl
+    implements MapLiteralEntry {
   /**
    * The expression computing the key with which the value will be associated.
    */
@@ -10868,7 +10748,7 @@
     implements SingleStringLiteral {}
 
 class SpreadElementImpl extends AstNodeImpl
-    implements CollectionElementImpl, MapElementImpl, SpreadElement {
+    implements CollectionElementImpl, SpreadElement {
   Token spreadOperator;
 
   ExpressionImpl _expression;
diff --git a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
index cad9671..4e04999 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
@@ -173,29 +173,6 @@
           semicolon);
 
   @override
-  CollectionForElement collectionForElement(
-          {Token awaitKeyword,
-          Token forKeyword,
-          Token leftParenthesis,
-          ForLoopParts forLoopParts,
-          Token rightParenthesis,
-          CollectionElement body}) =>
-      new CollectionForElementImpl(awaitKeyword, forKeyword, leftParenthesis,
-          forLoopParts, rightParenthesis, body);
-
-  @override
-  CollectionIfElement collectionIfElement(
-          {Token ifKeyword,
-          Token leftParenthesis,
-          Expression condition,
-          Token rightParenthesis,
-          CollectionElement thenElement,
-          Token elseKeyword,
-          CollectionElement elseElement}) =>
-      new CollectionIfElementImpl(ifKeyword, leftParenthesis, condition,
-          rightParenthesis, thenElement, elseKeyword, elseElement);
-
-  @override
   CommentReference commentReference(Token newKeyword, Identifier identifier) =>
       new CommentReferenceImpl(newKeyword, identifier);
 
@@ -482,6 +459,17 @@
           body);
 
   @override
+  ForElement forElement(
+          {Token awaitKeyword,
+          Token forKeyword,
+          Token leftParenthesis,
+          ForLoopParts forLoopParts,
+          Token rightParenthesis,
+          CollectionElement body}) =>
+      new ForElementImpl(awaitKeyword, forKeyword, leftParenthesis,
+          forLoopParts, rightParenthesis, body);
+
+  @override
   FormalParameterList formalParameterList(
           Token leftParenthesis,
           List<FormalParameter> parameters,
@@ -640,6 +628,18 @@
       new HideCombinatorImpl(keyword, hiddenNames);
 
   @override
+  IfElement ifElement(
+          {Token ifKeyword,
+          Token leftParenthesis,
+          Expression condition,
+          Token rightParenthesis,
+          CollectionElement thenElement,
+          Token elseKeyword,
+          CollectionElement elseElement}) =>
+      new IfElementImpl(ifKeyword, leftParenthesis, condition, rightParenthesis,
+          thenElement, elseKeyword, elseElement);
+
+  @override
   IfStatement ifStatement(
           Token ifKeyword,
           Token leftParenthesis,
@@ -752,29 +752,6 @@
           constKeyword, typeArguments, leftBracket, elements, rightBracket);
 
   @override
-  MapForElement mapForElement(
-          {Token awaitKeyword,
-          Token forKeyword,
-          Token leftParenthesis,
-          ForLoopParts forLoopParts,
-          Token rightParenthesis,
-          MapElement body}) =>
-      new MapForElementImpl(awaitKeyword, forKeyword, leftParenthesis,
-          forLoopParts, rightParenthesis, body);
-
-  @override
-  MapIfElement mapIfElement(
-          {Token ifKeyword,
-          Token leftParenthesis,
-          Expression condition,
-          Token rightParenthesis,
-          MapElement thenElement,
-          Token elseKeyword,
-          MapElement elseElement}) =>
-      new MapIfElementImpl(ifKeyword, leftParenthesis, condition,
-          rightParenthesis, thenElement, elseKeyword, elseElement);
-
-  @override
   MapLiteral mapLiteral(
           Token constKeyword,
           TypeArgumentList typeArguments,
@@ -789,7 +766,7 @@
           {Token constKeyword,
           TypeArgumentList typeArguments,
           Token leftBracket,
-          List<MapElement> entries,
+          List<CollectionElement> entries,
           Token rightBracket}) =>
       new MapLiteral2Impl(
           constKeyword, typeArguments, leftBracket, entries, rightBracket);
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index e38210b..59cec6b 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -249,26 +249,6 @@
   }
 
   @override
-  CollectionForElement visitCollectionForElement(CollectionForElement node) =>
-      astFactory.collectionForElement(
-          forKeyword: cloneToken(node.forKeyword),
-          leftParenthesis: cloneToken(node.leftParenthesis),
-          forLoopParts: cloneNode(node.forLoopParts),
-          rightParenthesis: cloneToken(node.rightParenthesis),
-          body: cloneNode(node.body));
-
-  @override
-  CollectionIfElement visitCollectionIfElement(CollectionIfElement node) =>
-      astFactory.collectionIfElement(
-          ifKeyword: cloneToken(node.ifKeyword),
-          leftParenthesis: cloneToken(node.leftParenthesis),
-          condition: cloneNode(node.condition),
-          rightParenthesis: cloneToken(node.rightParenthesis),
-          thenElement: cloneNode(node.thenElement),
-          elseKeyword: cloneToken(node.elseKeyword),
-          elseElement: cloneNode(node.elseElement));
-
-  @override
   Comment visitComment(Comment node) {
     if (node.isDocumentation) {
       return astFactory.documentationComment(
@@ -532,6 +512,14 @@
   }
 
   @override
+  ForElement visitForElement(ForElement node) => astFactory.forElement(
+      forKeyword: cloneToken(node.forKeyword),
+      leftParenthesis: cloneToken(node.leftParenthesis),
+      forLoopParts: cloneNode(node.forLoopParts),
+      rightParenthesis: cloneToken(node.rightParenthesis),
+      body: cloneNode(node.body));
+
+  @override
   FormalParameterList visitFormalParameterList(FormalParameterList node) =>
       astFactory.formalParameterList(
           cloneToken(node.leftParenthesis),
@@ -661,6 +649,16 @@
           cloneToken(node.keyword), cloneNodeList(node.hiddenNames));
 
   @override
+  IfElement visitIfElement(IfElement node) => astFactory.ifElement(
+      ifKeyword: cloneToken(node.ifKeyword),
+      leftParenthesis: cloneToken(node.leftParenthesis),
+      condition: cloneNode(node.condition),
+      rightParenthesis: cloneToken(node.rightParenthesis),
+      thenElement: cloneNode(node.thenElement),
+      elseKeyword: cloneToken(node.elseKeyword),
+      elseElement: cloneNode(node.elseElement));
+
+  @override
   IfStatement visitIfStatement(IfStatement node) => astFactory.ifStatement(
       cloneToken(node.ifKeyword),
       cloneToken(node.leftParenthesis),
@@ -778,25 +776,6 @@
       rightBracket: cloneToken(node.rightBracket));
 
   @override
-  MapForElement visitMapForElement(MapForElement node) =>
-      astFactory.mapForElement(
-          forKeyword: cloneToken(node.forKeyword),
-          leftParenthesis: cloneToken(node.leftParenthesis),
-          forLoopParts: cloneNode(node.forLoopParts),
-          rightParenthesis: cloneToken(node.rightParenthesis),
-          body: cloneNode(node.body));
-
-  @override
-  MapIfElement visitMapIfElement(MapIfElement node) => astFactory.mapIfElement(
-      ifKeyword: cloneToken(node.ifKeyword),
-      leftParenthesis: cloneToken(node.leftParenthesis),
-      condition: cloneNode(node.condition),
-      rightParenthesis: cloneToken(node.rightParenthesis),
-      thenElement: cloneNode(node.thenElement),
-      elseKeyword: cloneToken(node.elseKeyword),
-      elseElement: cloneNode(node.elseElement));
-
-  @override
   MapLiteral visitMapLiteral(MapLiteral node) => astFactory.mapLiteral(
       cloneToken(node.constKeyword),
       cloneNode(node.typeArguments),
@@ -1450,28 +1429,6 @@
   }
 
   @override
-  bool visitCollectionForElement(CollectionForElement node) {
-    CollectionForElement other = _other as CollectionForElement;
-    return isEqualTokens(node.forKeyword, other.forKeyword) &&
-        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
-        isEqualNodes(node.forLoopParts, other.forLoopParts) &&
-        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
-        isEqualNodes(node.body, other.body);
-  }
-
-  @override
-  bool visitCollectionIfElement(CollectionIfElement node) {
-    CollectionIfElement other = _other as CollectionIfElement;
-    return isEqualTokens(node.ifKeyword, other.ifKeyword) &&
-        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
-        isEqualNodes(node.condition, other.condition) &&
-        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
-        isEqualNodes(node.thenElement, other.thenElement) &&
-        isEqualTokens(node.elseKeyword, other.elseKeyword) &&
-        isEqualNodes(node.elseElement, other.elseElement);
-  }
-
-  @override
   bool visitComment(Comment node) {
     Comment other = _other as Comment;
     return _isEqualNodeLists(node.references, other.references);
@@ -1728,6 +1685,16 @@
   }
 
   @override
+  bool visitForElement(ForElement node) {
+    ForElement other = _other as ForElement;
+    return isEqualTokens(node.forKeyword, other.forKeyword) &&
+        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        isEqualNodes(node.forLoopParts, other.forLoopParts) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
+        isEqualNodes(node.body, other.body);
+  }
+
+  @override
   bool visitFormalParameterList(FormalParameterList node) {
     FormalParameterList other = _other as FormalParameterList;
     return isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
@@ -1871,6 +1838,18 @@
   }
 
   @override
+  bool visitIfElement(IfElement node) {
+    IfElement other = _other as IfElement;
+    return isEqualTokens(node.ifKeyword, other.ifKeyword) &&
+        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        isEqualNodes(node.condition, other.condition) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
+        isEqualNodes(node.thenElement, other.thenElement) &&
+        isEqualTokens(node.elseKeyword, other.elseKeyword) &&
+        isEqualNodes(node.elseElement, other.elseElement);
+  }
+
+  @override
   bool visitIfStatement(IfStatement node) {
     IfStatement other = _other as IfStatement;
     return isEqualTokens(node.ifKeyword, other.ifKeyword) &&
@@ -2005,28 +1984,6 @@
   }
 
   @override
-  bool visitMapForElement(MapForElement node) {
-    MapForElement other = _other as MapForElement;
-    return isEqualTokens(node.forKeyword, other.forKeyword) &&
-        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
-        isEqualNodes(node.forLoopParts, other.forLoopParts) &&
-        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
-        isEqualNodes(node.body, other.body);
-  }
-
-  @override
-  bool visitMapIfElement(MapIfElement node) {
-    MapIfElement other = _other as MapIfElement;
-    return isEqualTokens(node.ifKeyword, other.ifKeyword) &&
-        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
-        isEqualNodes(node.condition, other.condition) &&
-        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
-        isEqualNodes(node.thenElement, other.thenElement) &&
-        isEqualTokens(node.elseKeyword, other.elseKeyword) &&
-        isEqualNodes(node.elseElement, other.elseElement);
-  }
-
-  @override
   bool visitMapLiteral(MapLiteral node) {
     MapLiteral other = _other as MapLiteral;
     return isEqualTokens(node.constKeyword, other.constKeyword) &&
@@ -2788,26 +2745,6 @@
           _mapToken(node.semicolon));
 
   @override
-  CollectionForElement visitCollectionForElement(CollectionForElement node) =>
-      astFactory.collectionForElement(
-          forKeyword: _mapToken(node.forKeyword),
-          leftParenthesis: _mapToken(node.leftParenthesis),
-          forLoopParts: _cloneNode(node.forLoopParts),
-          rightParenthesis: _mapToken(node.rightParenthesis),
-          body: _cloneNode(node.body));
-
-  @override
-  CollectionIfElement visitCollectionIfElement(CollectionIfElement node) =>
-      astFactory.collectionIfElement(
-          ifKeyword: _mapToken(node.ifKeyword),
-          leftParenthesis: _mapToken(node.leftParenthesis),
-          condition: _cloneNode(node.condition),
-          rightParenthesis: _mapToken(node.rightParenthesis),
-          thenElement: _cloneNode(node.thenElement),
-          elseKeyword: _mapToken(node.elseKeyword),
-          elseElement: _cloneNode(node.elseElement));
-
-  @override
   Comment visitComment(Comment node) {
     if (node.isDocumentation) {
       return astFactory.documentationComment(
@@ -3063,6 +3000,14 @@
   }
 
   @override
+  ForElement visitForElement(ForElement node) => astFactory.forElement(
+      forKeyword: _mapToken(node.forKeyword),
+      leftParenthesis: _mapToken(node.leftParenthesis),
+      forLoopParts: _cloneNode(node.forLoopParts),
+      rightParenthesis: _mapToken(node.rightParenthesis),
+      body: _cloneNode(node.body));
+
+  @override
   FormalParameterList visitFormalParameterList(FormalParameterList node) =>
       astFactory.formalParameterList(
           _mapToken(node.leftParenthesis),
@@ -3204,6 +3149,16 @@
           _mapToken(node.keyword), _cloneNodeList(node.hiddenNames));
 
   @override
+  IfElement visitIfElement(IfElement node) => astFactory.ifElement(
+      ifKeyword: _mapToken(node.ifKeyword),
+      leftParenthesis: _mapToken(node.leftParenthesis),
+      condition: _cloneNode(node.condition),
+      rightParenthesis: _mapToken(node.rightParenthesis),
+      thenElement: _cloneNode(node.thenElement),
+      elseKeyword: _mapToken(node.elseKeyword),
+      elseElement: _cloneNode(node.elseElement));
+
+  @override
   IfStatement visitIfStatement(IfStatement node) => astFactory.ifStatement(
       _mapToken(node.ifKeyword),
       _mapToken(node.leftParenthesis),
@@ -3349,25 +3304,6 @@
       rightBracket: _mapToken(node.rightBracket));
 
   @override
-  MapForElement visitMapForElement(MapForElement node) =>
-      astFactory.mapForElement(
-          forKeyword: _mapToken(node.forKeyword),
-          leftParenthesis: _mapToken(node.leftParenthesis),
-          forLoopParts: _cloneNode(node.forLoopParts),
-          rightParenthesis: _mapToken(node.rightParenthesis),
-          body: _cloneNode(node.body));
-
-  @override
-  MapIfElement visitMapIfElement(MapIfElement node) => astFactory.mapIfElement(
-      ifKeyword: _mapToken(node.ifKeyword),
-      leftParenthesis: _mapToken(node.leftParenthesis),
-      condition: _cloneNode(node.condition),
-      rightParenthesis: _mapToken(node.rightParenthesis),
-      thenElement: _cloneNode(node.thenElement),
-      elseKeyword: _mapToken(node.elseKeyword),
-      elseElement: _cloneNode(node.elseElement));
-
-  @override
   MapLiteral visitMapLiteral(MapLiteral node) {
     MapLiteral copy = astFactory.mapLiteral(
         _mapToken(node.constKeyword),
@@ -4266,36 +4202,6 @@
   }
 
   @override
-  bool visitCollectionForElement(CollectionForElement node) {
-    if (identical(node.forLoopParts, _oldNode)) {
-      (node as CollectionForElementImpl).forLoopParts =
-          _newNode as ForLoopParts;
-      return true;
-    } else if (identical(node.body, _oldNode)) {
-      (node as CollectionForElementImpl).body = _newNode as CollectionElement;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitCollectionIfElement(CollectionIfElement node) {
-    if (identical(node.condition, _oldNode)) {
-      (node as CollectionIfElementImpl).condition = _newNode as Expression;
-      return true;
-    } else if (identical(node.thenElement, _oldNode)) {
-      (node as CollectionIfElementImpl).thenElement =
-          _newNode as CollectionElement;
-      return true;
-    } else if (identical(node.elseElement, _oldNode)) {
-      (node as CollectionIfElementImpl).elseElement =
-          _newNode as CollectionElement;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
   bool visitComment(Comment node) {
     if (_replaceInList(node.references)) {
       return true;
@@ -4583,6 +4489,18 @@
   }
 
   @override
+  bool visitForElement(ForElement node) {
+    if (identical(node.forLoopParts, _oldNode)) {
+      (node as ForElementImpl).forLoopParts = _newNode as ForLoopParts;
+      return true;
+    } else if (identical(node.body, _oldNode)) {
+      (node as ForElementImpl).body = _newNode as CollectionElement;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
   bool visitFormalParameterList(FormalParameterList node) {
     if (_replaceInList(node.parameters)) {
       return true;
@@ -4771,6 +4689,21 @@
   }
 
   @override
+  bool visitIfElement(IfElement node) {
+    if (identical(node.condition, _oldNode)) {
+      (node as IfElementImpl).condition = _newNode as Expression;
+      return true;
+    } else if (identical(node.thenElement, _oldNode)) {
+      (node as IfElementImpl).thenElement = _newNode as CollectionElement;
+      return true;
+    } else if (identical(node.elseElement, _oldNode)) {
+      (node as IfElementImpl).elseElement = _newNode as CollectionElement;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
   bool visitIfStatement(IfStatement node) {
     if (identical(node.condition, _oldNode)) {
       node.condition = _newNode as Expression;
@@ -4910,33 +4843,6 @@
   }
 
   @override
-  bool visitMapForElement(MapForElement node) {
-    if (identical(node.forLoopParts, _oldNode)) {
-      (node as MapForElementImpl).forLoopParts = _newNode as ForLoopParts;
-      return true;
-    } else if (identical(node.body, _oldNode)) {
-      (node as MapForElementImpl).body = _newNode as MapElement;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
-  bool visitMapIfElement(MapIfElement node) {
-    if (identical(node.condition, _oldNode)) {
-      (node as MapIfElementImpl).condition = _newNode as Expression;
-      return true;
-    } else if (identical(node.thenElement, _oldNode)) {
-      (node as MapIfElementImpl).thenElement = _newNode as MapElement;
-      return true;
-    } else if (identical(node.elseElement, _oldNode)) {
-      (node as MapIfElementImpl).elseElement = _newNode as MapElement;
-      return true;
-    }
-    return visitNode(node);
-  }
-
-  @override
   bool visitMapLiteral(MapLiteral node) {
     if (_replaceInList(node.entries)) {
       return true;
@@ -5702,30 +5608,6 @@
   }
 
   @override
-  bool visitCollectionForElement(CollectionForElement node) {
-    CollectionForElement toNode = this._toNode as CollectionForElement;
-    return _and(
-        _isEqualTokens(node.forKeyword, toNode.forKeyword),
-        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
-        _isEqualNodes(node.forLoopParts, toNode.forLoopParts),
-        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
-        _isEqualNodes(node.body, toNode.body));
-  }
-
-  @override
-  bool visitCollectionIfElement(CollectionIfElement node) {
-    CollectionIfElement toNode = this._toNode as CollectionIfElement;
-    return _and(
-        _isEqualTokens(node.ifKeyword, toNode.ifKeyword),
-        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
-        _isEqualNodes(node.condition, toNode.condition),
-        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
-        _isEqualNodes(node.thenElement, toNode.thenElement),
-        _isEqualTokens(node.elseKeyword, toNode.elseKeyword),
-        _isEqualNodes(node.elseElement, toNode.elseElement));
-  }
-
-  @override
   bool visitComment(Comment node) {
     Comment toNode = this._toNode as Comment;
     return _isEqualNodeLists(node.references, toNode.references);
@@ -6029,6 +5911,17 @@
   }
 
   @override
+  bool visitForElement(ForElement node) {
+    ForElement toNode = this._toNode as ForElement;
+    return _and(
+        _isEqualTokens(node.forKeyword, toNode.forKeyword),
+        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
+        _isEqualNodes(node.forLoopParts, toNode.forLoopParts),
+        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
+        _isEqualNodes(node.body, toNode.body));
+  }
+
+  @override
   bool visitFormalParameterList(FormalParameterList node) {
     FormalParameterList toNode = this._toNode as FormalParameterList;
     return _and(
@@ -6202,6 +6095,19 @@
   }
 
   @override
+  bool visitIfElement(IfElement node) {
+    IfElement toNode = this._toNode as IfElement;
+    return _and(
+        _isEqualTokens(node.ifKeyword, toNode.ifKeyword),
+        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
+        _isEqualNodes(node.condition, toNode.condition),
+        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
+        _isEqualNodes(node.thenElement, toNode.thenElement),
+        _isEqualTokens(node.elseKeyword, toNode.elseKeyword),
+        _isEqualNodes(node.elseElement, toNode.elseElement));
+  }
+
+  @override
   bool visitIfStatement(IfStatement node) {
     IfStatement toNode = this._toNode as IfStatement;
     return _and(
@@ -6382,30 +6288,6 @@
   }
 
   @override
-  bool visitMapForElement(MapForElement node) {
-    MapForElement toNode = this._toNode as MapForElement;
-    return _and(
-        _isEqualTokens(node.forKeyword, toNode.forKeyword),
-        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
-        _isEqualNodes(node.forLoopParts, toNode.forLoopParts),
-        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
-        _isEqualNodes(node.body, toNode.body));
-  }
-
-  @override
-  bool visitMapIfElement(MapIfElement node) {
-    MapIfElement toNode = this._toNode as MapIfElement;
-    return _and(
-        _isEqualTokens(node.ifKeyword, toNode.ifKeyword),
-        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
-        _isEqualNodes(node.condition, toNode.condition),
-        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
-        _isEqualNodes(node.thenElement, toNode.thenElement),
-        _isEqualTokens(node.elseKeyword, toNode.elseKeyword),
-        _isEqualNodes(node.elseElement, toNode.elseElement));
-  }
-
-  @override
   bool visitMapLiteral(MapLiteral node) {
     MapLiteral toNode = this._toNode as MapLiteral;
     if (_and(
@@ -7471,23 +7353,6 @@
   }
 
   @override
-  void visitCollectionForElement(CollectionForElement node) {
-    _writer.print('for (');
-    _visitNode(node.forLoopParts);
-    _writer.print(') ');
-    _visitNode(node.body);
-  }
-
-  @override
-  void visitCollectionIfElement(CollectionIfElement node) {
-    _writer.print('if (');
-    _visitNode(node.condition);
-    _writer.print(') ');
-    _visitNode(node.thenElement);
-    _visitNodeWithPrefix(' else ', node.elseElement);
-  }
-
-  @override
   void visitComment(Comment node) {}
 
   @override
@@ -7710,6 +7575,14 @@
   }
 
   @override
+  void visitForElement(ForElement node) {
+    _writer.print('for (');
+    _visitNode(node.forLoopParts);
+    _writer.print(') ');
+    _visitNode(node.body);
+  }
+
+  @override
   void visitFormalParameterList(FormalParameterList node) {
     String groupEnd = null;
     _writer.print('(');
@@ -7861,6 +7734,15 @@
   }
 
   @override
+  void visitIfElement(IfElement node) {
+    _writer.print('if (');
+    _visitNode(node.condition);
+    _writer.print(') ');
+    _visitNode(node.thenElement);
+    _visitNodeWithPrefix(' else ', node.elseElement);
+  }
+
+  @override
   void visitIfStatement(IfStatement node) {
     _writer.print("if (");
     _visitNode(node.condition);
@@ -7987,23 +7869,6 @@
   }
 
   @override
-  void visitMapForElement(MapForElement node) {
-    _writer.print('for (');
-    _visitNode(node.forLoopParts);
-    _writer.print(') ');
-    _visitNode(node.body);
-  }
-
-  @override
-  void visitMapIfElement(MapIfElement node) {
-    _writer.print('if (');
-    _visitNode(node.condition);
-    _writer.print(') ');
-    _visitNode(node.thenElement);
-    _visitNodeWithPrefix(' else ', node.elseElement);
-  }
-
-  @override
   void visitMapLiteral(MapLiteral node) {
     if (node.constKeyword != null) {
       _writer.print(node.constKeyword.lexeme);
@@ -8815,23 +8680,6 @@
   }
 
   @override
-  void visitCollectionForElement(CollectionForElement node) {
-    sink.write('for (');
-    safelyVisitNode(node.forLoopParts);
-    sink.write(') ');
-    safelyVisitNode(node.body);
-  }
-
-  @override
-  void visitCollectionIfElement(CollectionIfElement node) {
-    sink.write('if (');
-    safelyVisitNode(node.condition);
-    sink.write(') ');
-    safelyVisitNode(node.thenElement);
-    safelyVisitNodeWithPrefix(' else ', node.elseElement);
-  }
-
-  @override
   void visitComment(Comment node) {}
 
   @override
@@ -9054,6 +8902,14 @@
   }
 
   @override
+  void visitForElement(ForElement node) {
+    sink.write('for (');
+    safelyVisitNode(node.forLoopParts);
+    sink.write(') ');
+    safelyVisitNode(node.body);
+  }
+
+  @override
   void visitFormalParameterList(FormalParameterList node) {
     String groupEnd = null;
     sink.write('(');
@@ -9205,6 +9061,15 @@
   }
 
   @override
+  void visitIfElement(IfElement node) {
+    sink.write('if (');
+    safelyVisitNode(node.condition);
+    sink.write(') ');
+    safelyVisitNode(node.thenElement);
+    safelyVisitNodeWithPrefix(' else ', node.elseElement);
+  }
+
+  @override
   void visitIfStatement(IfStatement node) {
     sink.write("if (");
     safelyVisitNode(node.condition);
@@ -9328,23 +9193,6 @@
   }
 
   @override
-  void visitMapForElement(MapForElement node) {
-    sink.write('for (');
-    safelyVisitNode(node.forLoopParts);
-    sink.write(') ');
-    safelyVisitNode(node.body);
-  }
-
-  @override
-  void visitMapIfElement(MapIfElement node) {
-    sink.write('if (');
-    safelyVisitNode(node.condition);
-    sink.write(') ');
-    safelyVisitNode(node.thenElement);
-    safelyVisitNodeWithPrefix(' else ', node.elseElement);
-  }
-
-  @override
   void visitMapLiteral(MapLiteral node) {
     safelyVisitTokenWithSuffix(node.constKeyword, ' ');
     safelyVisitNodeWithSuffix(node.typeArguments, " ");
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 4e6bcd8..ee9cc60 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -1429,7 +1429,7 @@
     }
     Map<DartObjectImpl, DartObjectImpl> map = {};
     bool errorOccurred = false;
-    for (MapElement element in node.entries) {
+    for (CollectionElement element in node.entries) {
       errorOccurred = errorOccurred | _addElementsToMap(map, element);
     }
     if (errorOccurred) {
@@ -1660,7 +1660,7 @@
    * elements failed.
    */
   bool _addElementsToList(List<DartObject> list, CollectionElement element) {
-    if (element is CollectionIfElement) {
+    if (element is IfElement) {
       DartObjectImpl conditionResult = element.condition.accept(this);
       bool conditionValue = conditionResult?.toBoolValue();
       if (conditionValue == null) {
@@ -1697,8 +1697,8 @@
    * failed.
    */
   bool _addElementsToMap(
-      Map<DartObjectImpl, DartObjectImpl> map, MapElement element) {
-    if (element is MapIfElement) {
+      Map<DartObjectImpl, DartObjectImpl> map, CollectionElement element) {
+    if (element is IfElement) {
       DartObjectImpl conditionResult = element.condition.accept(this);
       bool conditionValue = conditionResult?.toBoolValue();
       if (conditionValue == null) {
@@ -1736,7 +1736,7 @@
    * elements failed.
    */
   bool _addElementsToSet(Set<DartObject> set, CollectionElement element) {
-    if (element is CollectionIfElement) {
+    if (element is IfElement) {
       DartObjectImpl conditionResult = element.condition.accept(this);
       bool conditionValue = conditionResult?.toBoolValue();
       if (conditionValue == null) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/exit_detector.dart b/pkg/analyzer/lib/src/dart/resolver/exit_detector.dart
index 71a1fd8..2f558cf 100644
--- a/pkg/analyzer/lib/src/dart/resolver/exit_detector.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/exit_detector.dart
@@ -115,83 +115,6 @@
       _nodeExits(node.target) || _visitExpressions(node.cascadeSections);
 
   @override
-  bool visitCollectionForElement(CollectionForElement node) {
-    bool outerBreakValue = _enclosingBlockContainsBreak;
-    _enclosingBlockContainsBreak = false;
-    try {
-      ForLoopParts forLoopParts = node.forLoopParts;
-      if (forLoopParts is ForParts) {
-        if (forLoopParts is ForPartsWithDeclarations) {
-          if (forLoopParts.variables != null &&
-              _visitVariableDeclarations(forLoopParts.variables.variables)) {
-            return true;
-          }
-        } else if (forLoopParts is ForPartsWithExpression) {
-          if (forLoopParts.initialization != null &&
-              _nodeExits(forLoopParts.initialization)) {
-            return true;
-          }
-        }
-        Expression conditionExpression = forLoopParts.condition;
-        if (conditionExpression != null && _nodeExits(conditionExpression)) {
-          return true;
-        }
-        if (_visitExpressions(forLoopParts.updaters)) {
-          return true;
-        }
-        bool blockReturns = _nodeExits(node.body);
-        // TODO(jwren) Do we want to take all constant expressions into account?
-        // If for(; true; ) (or for(;;)), and the body doesn't return or the body
-        // doesn't have a break, then return true.
-        bool implicitOrExplictTrue = conditionExpression == null ||
-            (conditionExpression is BooleanLiteral &&
-                conditionExpression.value);
-        if (implicitOrExplictTrue) {
-          if (blockReturns || !_enclosingBlockContainsBreak) {
-            return true;
-          }
-        }
-        return false;
-      } else if (forLoopParts is ForEachParts) {
-        bool iterableExits = _nodeExits(forLoopParts.iterable);
-        // Discard whether the for-each body exits; since the for-each iterable
-        // may be empty, execution may never enter the body, so it doesn't matter
-        // if it exits or not.  We still must visit the body, to accurately
-        // manage `_enclosingBlockBreaksLabel`.
-        _nodeExits(node.body);
-        return iterableExits;
-      }
-    } finally {
-      _enclosingBlockContainsBreak = outerBreakValue;
-    }
-    return false;
-  }
-
-  @override
-  bool visitCollectionIfElement(CollectionIfElement node) {
-    Expression conditionExpression = node.condition;
-    CollectionElement thenElement = node.thenElement;
-    CollectionElement elseElement = node.elseElement;
-    if (_nodeExits(conditionExpression)) {
-      return true;
-    }
-
-    bool conditionValue = _knownConditionValue(conditionExpression);
-    if (conditionValue == true) {
-      return _nodeExits(thenElement);
-    } else if (conditionValue == false && elseElement != null) {
-      return _nodeExits(elseElement);
-    }
-
-    bool thenExits = _nodeExits(thenElement);
-    bool elseExits = _nodeExits(elseElement);
-    if (thenElement == null || elseElement == null) {
-      return false;
-    }
-    return thenExits && elseExits;
-  }
-
-  @override
   bool visitConditionalExpression(ConditionalExpression node) {
     Expression conditionExpression = node.condition;
     Expression thenStatement = node.thenExpression;
@@ -272,6 +195,59 @@
   }
 
   @override
+  bool visitForElement(ForElement node) {
+    bool outerBreakValue = _enclosingBlockContainsBreak;
+    _enclosingBlockContainsBreak = false;
+    try {
+      ForLoopParts forLoopParts = node.forLoopParts;
+      if (forLoopParts is ForParts) {
+        if (forLoopParts is ForPartsWithDeclarations) {
+          if (forLoopParts.variables != null &&
+              _visitVariableDeclarations(forLoopParts.variables.variables)) {
+            return true;
+          }
+        } else if (forLoopParts is ForPartsWithExpression) {
+          if (forLoopParts.initialization != null &&
+              _nodeExits(forLoopParts.initialization)) {
+            return true;
+          }
+        }
+        Expression conditionExpression = forLoopParts.condition;
+        if (conditionExpression != null && _nodeExits(conditionExpression)) {
+          return true;
+        }
+        if (_visitExpressions(forLoopParts.updaters)) {
+          return true;
+        }
+        bool blockReturns = _nodeExits(node.body);
+        // TODO(jwren) Do we want to take all constant expressions into account?
+        // If for(; true; ) (or for(;;)), and the body doesn't return or the body
+        // doesn't have a break, then return true.
+        bool implicitOrExplictTrue = conditionExpression == null ||
+            (conditionExpression is BooleanLiteral &&
+                conditionExpression.value);
+        if (implicitOrExplictTrue) {
+          if (blockReturns || !_enclosingBlockContainsBreak) {
+            return true;
+          }
+        }
+        return false;
+      } else if (forLoopParts is ForEachParts) {
+        bool iterableExits = _nodeExits(forLoopParts.iterable);
+        // Discard whether the for-each body exits; since the for-each iterable
+        // may be empty, execution may never enter the body, so it doesn't matter
+        // if it exits or not.  We still must visit the body, to accurately
+        // manage `_enclosingBlockBreaksLabel`.
+        _nodeExits(node.body);
+        return iterableExits;
+      }
+    } finally {
+      _enclosingBlockContainsBreak = outerBreakValue;
+    }
+    return false;
+  }
+
+  @override
   bool visitForStatement(ForStatement node) {
     bool outerBreakValue = _enclosingBlockContainsBreak;
     _enclosingBlockContainsBreak = false;
@@ -387,6 +363,30 @@
   bool visitIdentifier(Identifier node) => false;
 
   @override
+  bool visitIfElement(IfElement node) {
+    Expression conditionExpression = node.condition;
+    CollectionElement thenElement = node.thenElement;
+    CollectionElement elseElement = node.elseElement;
+    if (_nodeExits(conditionExpression)) {
+      return true;
+    }
+
+    bool conditionValue = _knownConditionValue(conditionExpression);
+    if (conditionValue == true) {
+      return _nodeExits(thenElement);
+    } else if (conditionValue == false && elseElement != null) {
+      return _nodeExits(elseElement);
+    }
+
+    bool thenExits = _nodeExits(thenElement);
+    bool elseExits = _nodeExits(elseElement);
+    if (thenElement == null || elseElement == null) {
+      return false;
+    }
+    return thenExits && elseExits;
+  }
+
+  @override
   bool visitIfStatement(IfStatement node) {
     Expression conditionExpression = node.condition;
     Statement thenStatement = node.thenStatement;
@@ -458,85 +458,8 @@
   bool visitLiteral(Literal node) => false;
 
   @override
-  bool visitMapForElement(MapForElement node) {
-    bool outerBreakValue = _enclosingBlockContainsBreak;
-    _enclosingBlockContainsBreak = false;
-    try {
-      ForLoopParts forLoopParts = node.forLoopParts;
-      if (forLoopParts is ForParts) {
-        if (forLoopParts is ForPartsWithDeclarations) {
-          if (forLoopParts.variables != null &&
-              _visitVariableDeclarations(forLoopParts.variables.variables)) {
-            return true;
-          }
-        } else if (forLoopParts is ForPartsWithExpression) {
-          if (forLoopParts.initialization != null &&
-              _nodeExits(forLoopParts.initialization)) {
-            return true;
-          }
-        }
-        Expression conditionExpression = forLoopParts.condition;
-        if (conditionExpression != null && _nodeExits(conditionExpression)) {
-          return true;
-        }
-        if (_visitExpressions(forLoopParts.updaters)) {
-          return true;
-        }
-        bool blockReturns = _nodeExits(node.body);
-        // TODO(jwren) Do we want to take all constant expressions into account?
-        // If for(; true; ) (or for(;;)), and the body doesn't return or the body
-        // doesn't have a break, then return true.
-        bool implicitOrExplictTrue = conditionExpression == null ||
-            (conditionExpression is BooleanLiteral &&
-                conditionExpression.value);
-        if (implicitOrExplictTrue) {
-          if (blockReturns || !_enclosingBlockContainsBreak) {
-            return true;
-          }
-        }
-        return false;
-      } else if (forLoopParts is ForEachParts) {
-        bool iterableExits = _nodeExits(forLoopParts.iterable);
-        // Discard whether the for-each body exits; since the for-each iterable
-        // may be empty, execution may never enter the body, so it doesn't matter
-        // if it exits or not.  We still must visit the body, to accurately
-        // manage `_enclosingBlockBreaksLabel`.
-        _nodeExits(node.body);
-        return iterableExits;
-      }
-    } finally {
-      _enclosingBlockContainsBreak = outerBreakValue;
-    }
-    return false;
-  }
-
-  @override
-  bool visitMapIfElement(MapIfElement node) {
-    Expression conditionExpression = node.condition;
-    MapElement thenElement = node.thenElement;
-    MapElement elseElement = node.elseElement;
-    if (_nodeExits(conditionExpression)) {
-      return true;
-    }
-
-    bool conditionValue = _knownConditionValue(conditionExpression);
-    if (conditionValue == true) {
-      return _nodeExits(thenElement);
-    } else if (conditionValue == false && elseElement != null) {
-      return _nodeExits(elseElement);
-    }
-
-    bool thenExits = _nodeExits(thenElement);
-    bool elseExits = _nodeExits(elseElement);
-    if (thenElement == null || elseElement == null) {
-      return false;
-    }
-    return thenExits && elseExits;
-  }
-
-  @override
   bool visitMapLiteral2(MapLiteral2 node) {
-    for (MapElement entry in node.entries) {
+    for (CollectionElement entry in node.entries) {
       if (_nodeExits(entry)) {
         return true;
       }
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index b724e1a..572a8d8 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -1079,7 +1079,7 @@
     debugEvent("LiteralMap");
 
     if (enableControlFlowCollections || enableSpreadCollections) {
-      List<MapElement> entries = popMapElements(count);
+      List<CollectionElement> entries = popMapElements(count);
       TypeArgumentList typeArguments = pop();
       push(ast.mapLiteral2(
         constKeyword: constKeyword,
@@ -3153,12 +3153,13 @@
     return stack.popList(n, list, null);
   }
 
-  List<MapElement> popMapElements(int count) {
-    final entries = new List<MapElement>()..length = count;
+  List<CollectionElement> popMapElements(int count) {
+    final entries = new List<CollectionElement>()..length = count;
     for (int index = count - 1; index >= 0; --index) {
       var entry = pop();
-      entries[index] =
-          entry is _EntryInfo ? entry.asMapElement(ast) : entry as MapElement;
+      entries[index] = entry is _EntryInfo
+          ? entry.asMapElement(ast)
+          : entry as CollectionElement;
     }
     return entries;
   }
@@ -3278,7 +3279,7 @@
 
 abstract class _EntryInfo {
   CollectionElement asCollectionElement(AstFactory ast);
-  MapElement asMapElement(AstFactory ast);
+  CollectionElement asMapElement(AstFactory ast);
 }
 
 class _ForControlFlowInfo implements _EntryInfo {
@@ -3293,8 +3294,7 @@
       this.forLoopParts, this.rightParenthesis, this.entry);
 
   @override
-  CollectionElement asCollectionElement(AstFactory ast) =>
-      ast.collectionForElement(
+  CollectionElement asCollectionElement(AstFactory ast) => ast.forElement(
         awaitKeyword: awaitToken,
         forKeyword: forKeyword,
         leftParenthesis: leftParenthesis,
@@ -3306,14 +3306,15 @@
       );
 
   @override
-  MapElement asMapElement(AstFactory ast) => ast.mapForElement(
+  CollectionElement asMapElement(AstFactory ast) => ast.forElement(
         awaitKeyword: awaitToken,
         forKeyword: forKeyword,
         leftParenthesis: leftParenthesis,
         forLoopParts: forLoopParts,
         rightParenthesis: rightParenthesis,
-        body:
-            entry is _EntryInfo ? entry.asMapElement(ast) : entry as MapElement,
+        body: entry is _EntryInfo
+            ? entry.asMapElement(ast)
+            : entry as CollectionElement,
       );
 }
 
@@ -3336,8 +3337,7 @@
       this.elseElement);
 
   @override
-  CollectionElement asCollectionElement(AstFactory ast) =>
-      ast.collectionIfElement(
+  CollectionElement asCollectionElement(AstFactory ast) => ast.ifElement(
         ifKeyword: ifToken,
         leftParenthesis: leftParenthesis,
         condition: conditionExpression,
@@ -3352,17 +3352,17 @@
       );
 
   @override
-  MapElement asMapElement(AstFactory ast) => ast.mapIfElement(
+  CollectionElement asMapElement(AstFactory ast) => ast.ifElement(
         ifKeyword: ifToken,
         leftParenthesis: leftParenthesis,
         condition: conditionExpression,
         rightParenthesis: rightParenthesis,
         thenElement: thenElement is _EntryInfo
             ? thenElement.asMapElement(ast)
-            : thenElement as MapElement,
+            : thenElement as CollectionElement,
         elseKeyword: elseToken,
         elseElement: elseElement is _EntryInfo
             ? elseElement.asMapElement(ast)
-            : elseElement as MapElement,
+            : elseElement as CollectionElement,
       );
 }
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index ab7226c..55f766e 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -2567,10 +2567,10 @@
    */
   void _checkForCollectionElementTypeNotAssignableWithElementType(
       CollectionElement element, DartType elementType, ErrorCode errorCode) {
-    if (element is CollectionForElement) {
+    if (element is ForElement) {
       _checkForCollectionElementTypeNotAssignableWithElementType(
           element.body, elementType, errorCode);
-    } else if (element is CollectionIfElement) {
+    } else if (element is IfElement) {
       _checkForCollectionElementTypeNotAssignableWithElementType(
           element.thenElement, elementType, errorCode);
       _checkForCollectionElementTypeNotAssignableWithElementType(
@@ -4100,15 +4100,15 @@
    * [BestPracticesVerifier.checkForArgumentTypeNotAssignableWithExpectedTypes].
    */
   void _checkForMapElementTypeNotAssignableWithKeyOrValueType(
-      MapElement element,
+      CollectionElement element,
       DartType keyType,
       DartType valueType,
       ErrorCode keyErrorCode,
       ErrorCode valueErrorCode) {
-    if (element is MapForElement) {
+    if (element is ForElement) {
       _checkForMapElementTypeNotAssignableWithKeyOrValueType(
           element.body, keyType, valueType, keyErrorCode, valueErrorCode);
-    } else if (element is MapIfElement) {
+    } else if (element is IfElement) {
       _checkForMapElementTypeNotAssignableWithKeyOrValueType(
           element.thenElement,
           keyType,
@@ -4214,8 +4214,8 @@
     DartType valueType = typeArguments[1];
 
     bool isConst = literal.isConst;
-    NodeList<MapElement> entries = literal.entries;
-    for (MapElement entry in entries) {
+    NodeList<CollectionElement> entries = literal.entries;
+    for (CollectionElement entry in entries) {
       if (isConst) {
         // TODO(paulberry): this error should be based on the actual type of the
         // list element, not the static type.  See dartbug.com/21119.
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 389d665..e10c1fd 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1544,34 +1544,6 @@
   }
 
   @override
-  void visitCollectionIfElement(CollectionIfElement node) {
-    Expression conditionExpression = node.condition;
-    conditionExpression?.accept(this);
-    if (!_isDebugConstant(conditionExpression)) {
-      EvaluationResultImpl result =
-          _getConstantBooleanValue(conditionExpression);
-      if (result != null) {
-        if (result.value.toBoolValue() == true) {
-          // Report error on else block: if(true) {} else {!}
-          CollectionElement elseElement = node.elseElement;
-          if (elseElement != null) {
-            _errorReporter.reportErrorForNode(HintCode.DEAD_CODE, elseElement);
-            node.thenElement?.accept(this);
-            return;
-          }
-        } else {
-          // Report error on if block: if (false) {!} else {}
-          _errorReporter.reportErrorForNode(
-              HintCode.DEAD_CODE, node.thenElement);
-          node.elseElement?.accept(this);
-          return;
-        }
-      }
-    }
-    super.visitCollectionIfElement(node);
-  }
-
-  @override
   void visitConditionalExpression(ConditionalExpression node) {
     Expression conditionExpression = node.condition;
     conditionExpression?.accept(this);
@@ -1618,6 +1590,34 @@
   }
 
   @override
+  void visitIfElement(IfElement node) {
+    Expression conditionExpression = node.condition;
+    conditionExpression?.accept(this);
+    if (!_isDebugConstant(conditionExpression)) {
+      EvaluationResultImpl result =
+          _getConstantBooleanValue(conditionExpression);
+      if (result != null) {
+        if (result.value.toBoolValue() == true) {
+          // Report error on else block: if(true) {} else {!}
+          CollectionElement elseElement = node.elseElement;
+          if (elseElement != null) {
+            _errorReporter.reportErrorForNode(HintCode.DEAD_CODE, elseElement);
+            node.thenElement?.accept(this);
+            return;
+          }
+        } else {
+          // Report error on if block: if (false) {!} else {}
+          _errorReporter.reportErrorForNode(
+              HintCode.DEAD_CODE, node.thenElement);
+          node.elseElement?.accept(this);
+          return;
+        }
+      }
+    }
+    super.visitIfElement(node);
+  }
+
+  @override
   void visitIfStatement(IfStatement node) {
     Expression conditionExpression = node.condition;
     conditionExpression?.accept(this);
@@ -1673,34 +1673,6 @@
   }
 
   @override
-  void visitMapIfElement(MapIfElement node) {
-    Expression conditionExpression = node.condition;
-    conditionExpression?.accept(this);
-    if (!_isDebugConstant(conditionExpression)) {
-      EvaluationResultImpl result =
-          _getConstantBooleanValue(conditionExpression);
-      if (result != null) {
-        if (result.value.toBoolValue() == true) {
-          // Report error on else block: if(true) {} else {!}
-          MapElement elseElement = node.elseElement;
-          if (elseElement != null) {
-            _errorReporter.reportErrorForNode(HintCode.DEAD_CODE, elseElement);
-            node.thenElement?.accept(this);
-            return;
-          }
-        } else {
-          // Report error on if block: if (false) {!} else {}
-          _errorReporter.reportErrorForNode(
-              HintCode.DEAD_CODE, node.thenElement);
-          node.elseElement?.accept(this);
-          return;
-        }
-      }
-    }
-    super.visitMapIfElement(node);
-  }
-
-  @override
   void visitSwitchCase(SwitchCase node) {
     _checkForDeadStatementsInNodeList(node.statements, allowMandated: true);
     super.visitSwitchCase(node);
@@ -4111,84 +4083,6 @@
   }
 
   @override
-  void visitCollectionForElement(CollectionForElement node) {
-    ForLoopParts forLoopParts = node.forLoopParts;
-    if (forLoopParts is ForParts) {
-      if (forLoopParts is ForPartsWithDeclarations) {
-        forLoopParts.variables?.accept(this);
-      } else if (forLoopParts is ForPartsWithExpression) {
-        forLoopParts.initialization?.accept(this);
-      }
-      InferenceContext.setType(forLoopParts.condition, typeProvider.boolType);
-      forLoopParts.condition?.accept(this);
-      node.body?.accept(this);
-      forLoopParts.updaters.accept(this);
-    } else if (forLoopParts is ForEachParts) {
-      Expression iterable = forLoopParts.iterable;
-      DeclaredIdentifier loopVariable;
-      DartType valueType;
-      if (forLoopParts is ForEachPartsWithDeclaration) {
-        loopVariable = forLoopParts.loopVariable;
-        valueType = loopVariable?.type?.type ?? UnknownInferredType.instance;
-      } else if (forLoopParts is ForEachPartsWithIdentifier) {
-        SimpleIdentifier identifier = forLoopParts.identifier;
-        identifier?.accept(this);
-        Element element = identifier?.staticElement;
-        if (element is VariableElement) {
-          valueType = element.type;
-        } else if (element is PropertyAccessorElement) {
-          if (element.parameters.isNotEmpty) {
-            valueType = element.parameters[0].type;
-          }
-        }
-      }
-
-      if (valueType != null) {
-        InterfaceType targetType = (node.awaitKeyword == null)
-            ? typeProvider.iterableType
-            : typeProvider.streamType;
-        InferenceContext.setType(iterable, targetType.instantiate([valueType]));
-      }
-      //
-      // We visit the iterator before the loop variable because the loop
-      // variable cannot be in scope while visiting the iterator.
-      //
-      iterable?.accept(this);
-      loopVariable?.accept(this);
-      node.body?.accept(this);
-
-      node.accept(elementResolver);
-      node.accept(typeAnalyzer);
-    }
-  }
-
-  @override
-  void visitCollectionIfElement(CollectionIfElement node) {
-    Expression condition = node.condition;
-    InferenceContext.setType(condition, typeProvider.boolType);
-    condition?.accept(this);
-    CollectionElement thenElement = node.thenElement;
-    if (thenElement != null) {
-      _promoteManager.enterScope();
-      try {
-        // Type promotion.
-        _promoteTypes(condition);
-        _clearTypePromotionsIfPotentiallyMutatedIn(thenElement);
-        _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
-            thenElement);
-        // Visit "then".
-        thenElement.accept(this);
-      } finally {
-        _promoteManager.exitScope();
-      }
-    }
-    node.elseElement?.accept(this);
-
-    node.accept(elementResolver);
-    node.accept(typeAnalyzer);
-  }
-
-  @override
   void visitComment(Comment node) {
     AstNode parent = node.parent;
     if (parent is FunctionDeclaration ||
@@ -4448,6 +4342,58 @@
   }
 
   @override
+  void visitForElement(ForElement node) {
+    ForLoopParts forLoopParts = node.forLoopParts;
+    if (forLoopParts is ForParts) {
+      if (forLoopParts is ForPartsWithDeclarations) {
+        forLoopParts.variables?.accept(this);
+      } else if (forLoopParts is ForPartsWithExpression) {
+        forLoopParts.initialization?.accept(this);
+      }
+      InferenceContext.setType(forLoopParts.condition, typeProvider.boolType);
+      forLoopParts.condition?.accept(this);
+      node.body?.accept(this);
+      forLoopParts.updaters.accept(this);
+    } else if (forLoopParts is ForEachParts) {
+      Expression iterable = forLoopParts.iterable;
+      DeclaredIdentifier loopVariable;
+      DartType valueType;
+      if (forLoopParts is ForEachPartsWithDeclaration) {
+        loopVariable = forLoopParts.loopVariable;
+        valueType = loopVariable?.type?.type ?? UnknownInferredType.instance;
+      } else if (forLoopParts is ForEachPartsWithIdentifier) {
+        SimpleIdentifier identifier = forLoopParts.identifier;
+        identifier?.accept(this);
+        Element element = identifier?.staticElement;
+        if (element is VariableElement) {
+          valueType = element.type;
+        } else if (element is PropertyAccessorElement) {
+          if (element.parameters.isNotEmpty) {
+            valueType = element.parameters[0].type;
+          }
+        }
+      }
+
+      if (valueType != null) {
+        InterfaceType targetType = (node.awaitKeyword == null)
+            ? typeProvider.iterableType
+            : typeProvider.streamType;
+        InferenceContext.setType(iterable, targetType.instantiate([valueType]));
+      }
+      //
+      // We visit the iterator before the loop variable because the loop
+      // variable cannot be in scope while visiting the iterator.
+      //
+      iterable?.accept(this);
+      loopVariable?.accept(this);
+      node.body?.accept(this);
+
+      node.accept(elementResolver);
+      node.accept(typeAnalyzer);
+    }
+  }
+
+  @override
   void visitForStatement2InScope(ForStatement2 node) {
     ForLoopParts forLoopParts = node.forLoopParts;
     if (forLoopParts is ForParts) {
@@ -4607,6 +4553,32 @@
   void visitHideCombinator(HideCombinator node) {}
 
   @override
+  void visitIfElement(IfElement node) {
+    Expression condition = node.condition;
+    InferenceContext.setType(condition, typeProvider.boolType);
+    condition?.accept(this);
+    CollectionElement thenElement = node.thenElement;
+    if (thenElement != null) {
+      _promoteManager.enterScope();
+      try {
+        // Type promotion.
+        _promoteTypes(condition);
+        _clearTypePromotionsIfPotentiallyMutatedIn(thenElement);
+        _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
+            thenElement);
+        // Visit "then".
+        thenElement.accept(this);
+      } finally {
+        _promoteManager.exitScope();
+      }
+    }
+    node.elseElement?.accept(this);
+
+    node.accept(elementResolver);
+    node.accept(typeAnalyzer);
+  }
+
+  @override
   void visitIfStatement(IfStatement node) {
     Expression condition = node.condition;
     InferenceContext.setType(condition, typeProvider.boolType);
@@ -4710,90 +4682,6 @@
   }
 
   @override
-  void visitMapForElement(MapForElement node) {
-    ForLoopParts forLoopParts = node.forLoopParts;
-    if (forLoopParts is ForParts) {
-      if (forLoopParts is ForPartsWithDeclarations) {
-        forLoopParts.variables?.accept(this);
-      } else if (forLoopParts is ForPartsWithExpression) {
-        forLoopParts.initialization?.accept(this);
-      }
-      InferenceContext.setType(forLoopParts.condition, typeProvider.boolType);
-      forLoopParts.condition?.accept(this);
-      node.body?.accept(this);
-      forLoopParts.updaters.accept(this);
-    } else if (forLoopParts is ForEachParts) {
-      Expression iterable = forLoopParts.iterable;
-      DeclaredIdentifier loopVariable;
-      SimpleIdentifier identifier;
-      if (forLoopParts is ForEachPartsWithDeclaration) {
-        loopVariable = forLoopParts.loopVariable;
-      } else if (forLoopParts is ForEachPartsWithIdentifier) {
-        identifier = forLoopParts.identifier;
-        identifier?.accept(this);
-      }
-
-      DartType valueType;
-      if (loopVariable != null) {
-        TypeAnnotation typeAnnotation = loopVariable.type;
-        valueType = typeAnnotation?.type ?? UnknownInferredType.instance;
-      }
-      if (identifier != null) {
-        Element element = identifier.staticElement;
-        if (element is VariableElement) {
-          valueType = element.type;
-        } else if (element is PropertyAccessorElement) {
-          if (element.parameters.isNotEmpty) {
-            valueType = element.parameters[0].type;
-          }
-        }
-      }
-      if (valueType != null) {
-        InterfaceType targetType = (node.awaitKeyword == null)
-            ? typeProvider.iterableType
-            : typeProvider.streamType;
-        InferenceContext.setType(iterable, targetType.instantiate([valueType]));
-      }
-      //
-      // We visit the iterator before the loop variable because the loop variable
-      // cannot be in scope while visiting the iterator.
-      //
-      iterable?.accept(this);
-      loopVariable?.accept(this);
-      node.body?.accept(this);
-
-      node.accept(elementResolver);
-      node.accept(typeAnalyzer);
-    }
-  }
-
-  @override
-  void visitMapIfElement(MapIfElement node) {
-    Expression condition = node.condition;
-    InferenceContext.setType(condition, typeProvider.boolType);
-    condition?.accept(this);
-    MapElement thenElement = node.thenElement;
-    if (thenElement != null) {
-      _promoteManager.enterScope();
-      try {
-        // Type promotion.
-        _promoteTypes(condition);
-        _clearTypePromotionsIfPotentiallyMutatedIn(thenElement);
-        _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
-            thenElement);
-        // Visit "then".
-        thenElement.accept(this);
-      } finally {
-        _promoteManager.exitScope();
-      }
-    }
-    node.elseElement?.accept(this);
-
-    node.accept(elementResolver);
-    node.accept(typeAnalyzer);
-  }
-
-  @override
   void visitMapLiteral(MapLiteral node) {
     InterfaceType mapT;
     if (node.typeArguments != null) {
@@ -4851,10 +4739,10 @@
       DartType kType = mapT.typeArguments[0];
       DartType vType = mapT.typeArguments[1];
 
-      void pushTypesDown(MapElement element) {
-        if (element is MapForElement) {
+      void pushTypesDown(CollectionElement element) {
+        if (element is ForElement) {
           pushTypesDown(element.body);
-        } else if (element is MapIfElement) {
+        } else if (element is IfElement) {
           pushTypesDown(element.thenElement);
           pushTypesDown(element.elseElement);
         } else if (element is MapLiteralEntry) {
@@ -4865,7 +4753,7 @@
         }
       }
 
-      for (MapElement element in node.entries) {
+      for (CollectionElement element in node.entries) {
         pushTypesDown(element);
       }
       InferenceContext.setType(node, mapT);
@@ -5475,9 +5363,9 @@
 
   void _pushCollectionTypesDown(
       CollectionElement element, ParameterizedType collectionType) {
-    if (element is CollectionForElement) {
+    if (element is ForElement) {
       _pushCollectionTypesDown(element.body, collectionType);
-    } else if (element is CollectionIfElement) {
+    } else if (element is IfElement) {
       _pushCollectionTypesDown(element.thenElement, collectionType);
       _pushCollectionTypesDown(element.elseElement, collectionType);
     } else if (element is Expression) {
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 8453c32..23871b8 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -1498,9 +1498,9 @@
   }
 
   DartType _computeElementType(CollectionElement element) {
-    if (element is CollectionForElement) {
+    if (element is ForElement) {
       return _computeElementType(element.body);
-    } else if (element is CollectionIfElement) {
+    } else if (element is IfElement) {
       DartType thenType = _computeElementType(element.thenElement);
       if (element.elseElement == null) {
         return thenType;
@@ -1536,10 +1536,10 @@
     return _dynamicType;
   }
 
-  DartType _computeKeyType(MapElement element) {
-    if (element is MapForElement) {
+  DartType _computeKeyType(CollectionElement element) {
+    if (element is ForElement) {
       return _computeKeyType(element.body);
-    } else if (element is MapIfElement) {
+    } else if (element is IfElement) {
       DartType thenType = _computeKeyType(element.thenElement);
       if (element.elseElement == null) {
         return thenType;
@@ -1626,10 +1626,10 @@
     return returnType.type;
   }
 
-  DartType _computeValueType(MapElement element) {
-    if (element is MapForElement) {
+  DartType _computeValueType(CollectionElement element) {
+    if (element is ForElement) {
       return _computeValueType(element.body);
-    } else if (element is MapIfElement) {
+    } else if (element is IfElement) {
       DartType thenType = _computeValueType(element.thenElement);
       if (element.elseElement == null) {
         return thenType;
diff --git a/pkg/analyzer/lib/src/lint/linter_visitor.dart b/pkg/analyzer/lib/src/lint/linter_visitor.dart
index 54d81f6..98ba52c 100644
--- a/pkg/analyzer/lib/src/lint/linter_visitor.dart
+++ b/pkg/analyzer/lib/src/lint/linter_visitor.dart
@@ -109,18 +109,6 @@
   }
 
   @override
-  void visitCollectionForElement(CollectionForElement node) {
-    _runSubscriptions(node, registry._forCollectionForElement);
-    super.visitCollectionForElement(node);
-  }
-
-  @override
-  void visitCollectionIfElement(CollectionIfElement node) {
-    _runSubscriptions(node, registry._forCollectionIfElement);
-    super.visitCollectionIfElement(node);
-  }
-
-  @override
   void visitComment(Comment node) {
     _runSubscriptions(node, registry._forComment);
     super.visitComment(node);
@@ -283,6 +271,12 @@
   }
 
   @override
+  void visitForElement(ForElement node) {
+    _runSubscriptions(node, registry._forForElement);
+    super.visitForElement(node);
+  }
+
+  @override
   void visitFormalParameterList(FormalParameterList node) {
     _runSubscriptions(node, registry._forFormalParameterList);
     super.visitFormalParameterList(node);
@@ -367,6 +361,12 @@
   }
 
   @override
+  void visitIfElement(IfElement node) {
+    _runSubscriptions(node, registry._forIfElement);
+    super.visitIfElement(node);
+  }
+
+  @override
   void visitIfStatement(IfStatement node) {
     _runSubscriptions(node, registry._forIfStatement);
     super.visitIfStatement(node);
@@ -457,18 +457,6 @@
   }
 
   @override
-  void visitMapForElement(MapForElement node) {
-    _runSubscriptions(node, registry._forMapForElement);
-    super.visitMapForElement(node);
-  }
-
-  @override
-  void visitMapIfElement(MapIfElement node) {
-    _runSubscriptions(node, registry._forMapIfElement);
-    super.visitMapIfElement(node);
-  }
-
-  @override
   void visitMapLiteral(MapLiteral node) {
     _runSubscriptions(node, registry._forMapLiteral);
     super.visitMapLiteral(node);
@@ -779,8 +767,6 @@
   final List<_Subscription<CatchClause>> _forCatchClause = [];
   final List<_Subscription<ClassDeclaration>> _forClassDeclaration = [];
   final List<_Subscription<ClassTypeAlias>> _forClassTypeAlias = [];
-  final List<_Subscription<CollectionForElement>> _forCollectionForElement = [];
-  final List<_Subscription<CollectionIfElement>> _forCollectionIfElement = [];
   final List<_Subscription<Comment>> _forComment = [];
   final List<_Subscription<CommentReference>> _forCommentReference = [];
   final List<_Subscription<CompilationUnit>> _forCompilationUnit = [];
@@ -816,6 +802,7 @@
   final List<_Subscription<ForEachPartsWithIdentifier>>
       _forForEachPartsWithIdentifier = [];
   final List<_Subscription<ForEachStatement>> _forForEachStatement = [];
+  final List<_Subscription<ForElement>> _forForElement = [];
   final List<_Subscription<FormalParameterList>> _forFormalParameterList = [];
   final List<_Subscription<ForPartsWithDeclarations>>
       _forForPartsWithDeclarations = [];
@@ -835,6 +822,7 @@
   final List<_Subscription<GenericFunctionType>> _forGenericFunctionType = [];
   final List<_Subscription<GenericTypeAlias>> _forGenericTypeAlias = [];
   final List<_Subscription<HideCombinator>> _forHideCombinator = [];
+  final List<_Subscription<IfElement>> _forIfElement = [];
   final List<_Subscription<IfStatement>> _forIfStatement = [];
   final List<_Subscription<ImplementsClause>> _forImplementsClause = [];
   final List<_Subscription<ImportDirective>> _forImportDirective = [];
@@ -852,8 +840,6 @@
   final List<_Subscription<LibraryIdentifier>> _forLibraryIdentifier = [];
   final List<_Subscription<ListLiteral>> _forListLiteral = [];
   final List<_Subscription<ListLiteral2>> _forListLiteral2 = [];
-  final List<_Subscription<MapForElement>> _forMapForElement = [];
-  final List<_Subscription<MapIfElement>> _forMapIfElement = [];
   final List<_Subscription<MapLiteral>> _forMapLiteral = [];
   final List<_Subscription<MapLiteral2>> _forMapLiteral2 = [];
   final List<_Subscription<MapLiteralEntry>> _forMapLiteralEntry = [];
@@ -981,16 +967,6 @@
         .add(new _Subscription(linter, visitor, _getTimer(linter)));
   }
 
-  void addCollectionForElement(LintRule linter, AstVisitor visitor) {
-    _forCollectionForElement
-        .add(new _Subscription(linter, visitor, _getTimer(linter)));
-  }
-
-  void addCollectionIfElement(LintRule linter, AstVisitor visitor) {
-    _forCollectionIfElement
-        .add(new _Subscription(linter, visitor, _getTimer(linter)));
-  }
-
   void addComment(LintRule linter, AstVisitor visitor) {
     _forComment.add(new _Subscription(linter, visitor, _getTimer(linter)));
   }
@@ -1123,6 +1099,10 @@
         .add(new _Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addForElement(LintRule linter, AstVisitor visitor) {
+    _forForElement.add(new _Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addFormalParameterList(LintRule linter, AstVisitor visitor) {
     _forFormalParameterList
         .add(new _Subscription(linter, visitor, _getTimer(linter)));
@@ -1192,6 +1172,10 @@
         .add(new _Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addIfElement(LintRule linter, AstVisitor visitor) {
+    _forIfElement.add(new _Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addIfStatement(LintRule linter, AstVisitor visitor) {
     _forIfStatement.add(new _Subscription(linter, visitor, _getTimer(linter)));
   }
@@ -1262,15 +1246,6 @@
     _forListLiteral2.add(new _Subscription(linter, visitor, _getTimer(linter)));
   }
 
-  void addMapForElement(LintRule linter, AstVisitor visitor) {
-    _forMapForElement
-        .add(new _Subscription(linter, visitor, _getTimer(linter)));
-  }
-
-  void addMapIfElement(LintRule linter, AstVisitor visitor) {
-    _forMapIfElement.add(new _Subscription(linter, visitor, _getTimer(linter)));
-  }
-
   void addMapLiteral(LintRule linter, AstVisitor visitor) {
     _forMapLiteral.add(new _Subscription(linter, visitor, _getTimer(linter)));
   }
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index ad2424c..da18f90 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -166,9 +166,9 @@
 
   void checkCollectionElement(
       CollectionElement element, DartType expectedType) {
-    if (element is CollectionForElement) {
+    if (element is ForElement) {
       checkCollectionElement(element.body, expectedType);
-    } else if (element is CollectionIfElement) {
+    } else if (element is IfElement) {
       checkCollectionElement(element.thenElement, expectedType);
       checkCollectionElement(element.elseElement, expectedType);
     } else if (element is Expression) {
@@ -188,11 +188,11 @@
     }
   }
 
-  void checkMapElement(MapElement element, DartType expectedKeyType,
+  void checkMapElement(CollectionElement element, DartType expectedKeyType,
       DartType expectedValueType) {
-    if (element is MapForElement) {
+    if (element is ForElement) {
       checkMapElement(element.body, expectedKeyType, expectedValueType);
-    } else if (element is MapIfElement) {
+    } else if (element is IfElement) {
       checkMapElement(element.thenElement, expectedKeyType, expectedValueType);
       checkMapElement(element.elseElement, expectedKeyType, expectedValueType);
     } else if (element is MapLiteralEntry) {
@@ -609,7 +609,7 @@
         }
       }
     }
-    NodeList<MapElement> entries = node.entries;
+    NodeList<CollectionElement> entries = node.entries;
     for (int i = 0; i < entries.length; i++) {
       checkMapElement(entries[i], keyType, valueType);
     }
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 7dbd7f4..4809b48 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -135,7 +135,7 @@
     IntegerLiteral first = list.elements[0];
     expect(first.value, 1);
 
-    CollectionForElement second = list.elements[1];
+    ForElement second = list.elements[1];
     expect(second.awaitKeyword, isNotNull);
     expect(second.forKeyword.isKeyword, isTrue);
     expect(second.leftParenthesis.lexeme, '(');
@@ -157,7 +157,7 @@
     IntegerLiteral first = list.elements[0];
     expect(first.value, 1);
 
-    CollectionForElement second = list.elements[1];
+    ForElement second = list.elements[1];
     expect(second.awaitKeyword, isNotNull);
     expect(second.forKeyword.isKeyword, isTrue);
     expect(second.leftParenthesis.lexeme, '(');
@@ -169,7 +169,7 @@
     SimpleIdentifier iterable = forLoopParts.iterable;
     expect(iterable.name, 'list');
 
-    CollectionIfElement body = second.body;
+    IfElement body = second.body;
     SimpleIdentifier condition = body.condition;
     expect(condition.name, 'c');
     IntegerLiteral thenElement = body.thenElement;
@@ -183,7 +183,7 @@
     IntegerLiteral first = list.elements[0];
     expect(first.value, 1);
 
-    CollectionForElement second = list.elements[1];
+    ForElement second = list.elements[1];
     expect(second.awaitKeyword, isNull);
     expect(second.forKeyword.isKeyword, isTrue);
     expect(second.leftParenthesis.lexeme, '(');
@@ -205,7 +205,7 @@
     IntegerLiteral first = list.elements[0];
     expect(first.value, 1);
 
-    CollectionIfElement second = list.elements[1];
+    IfElement second = list.elements[1];
     BooleanLiteral condition = second.condition;
     expect(condition.value, isTrue);
     IntegerLiteral thenElement = second.thenElement;
@@ -219,7 +219,7 @@
     IntegerLiteral first = list.elements[0];
     expect(first.value, 1);
 
-    CollectionIfElement second = list.elements[1];
+    IfElement second = list.elements[1];
     BooleanLiteral condition = second.condition;
     expect(condition.value, isTrue);
     IntegerLiteral thenElement = second.thenElement;
@@ -235,13 +235,13 @@
     IntegerLiteral first = list.elements[0];
     expect(first.value, 1);
 
-    CollectionIfElement second = list.elements[1];
+    IfElement second = list.elements[1];
     BooleanLiteral condition = second.condition;
     expect(condition.value, isTrue);
     IntegerLiteral thenElement = second.thenElement;
     expect(thenElement.value, 2);
 
-    CollectionForElement elseElement = second.elseElement;
+    ForElement elseElement = second.elseElement;
     ForEachPartsWithIdentifier forLoopParts = elseElement.forLoopParts;
     expect(forLoopParts.identifier.name, 'a');
 
@@ -249,17 +249,33 @@
     expect(forValue.value, 5);
   }
 
+  void test_listLiteral_ifElseSpread() {
+    ListLiteral2 list =
+        parseCollectionLiteral('[1, if (true) ...[2] else ...?[5]]');
+    expect(list.elements, hasLength(2));
+    IntegerLiteral first = list.elements[0];
+    expect(first.value, 1);
+
+    IfElement second = list.elements[1];
+    BooleanLiteral condition = second.condition;
+    expect(condition.value, isTrue);
+    SpreadElement thenElement = second.thenElement;
+    expect(thenElement.spreadOperator.lexeme, '...');
+    SpreadElement elseElement = second.elseElement;
+    expect(elseElement.spreadOperator.lexeme, '...?');
+  }
+
   void test_listLiteral_ifFor() {
     ListLiteral2 list = parseCollectionLiteral('[1, if (true) for (a in b) 2]');
     expect(list.elements, hasLength(2));
     IntegerLiteral first = list.elements[0];
     expect(first.value, 1);
 
-    CollectionIfElement second = list.elements[1];
+    IfElement second = list.elements[1];
     BooleanLiteral condition = second.condition;
     expect(condition.value, isTrue);
 
-    CollectionForElement thenElement = second.thenElement;
+    ForElement thenElement = second.thenElement;
     ForEachPartsWithIdentifier forLoopParts = thenElement.forLoopParts;
     expect(forLoopParts.identifier.name, 'a');
 
@@ -274,7 +290,7 @@
     IntegerLiteral first = list.elements[0];
     expect(first.value, 1);
 
-    CollectionIfElement second = list.elements[1];
+    IfElement second = list.elements[1];
     BooleanLiteral condition = second.condition;
     expect(condition.value, isTrue);
     SpreadElement thenElement = second.thenElement;
@@ -282,22 +298,6 @@
     expect(second.elseElement, isNull);
   }
 
-  void test_listLiteral_ifElseSpread() {
-    ListLiteral2 list =
-        parseCollectionLiteral('[1, if (true) ...[2] else ...?[5]]');
-    expect(list.elements, hasLength(2));
-    IntegerLiteral first = list.elements[0];
-    expect(first.value, 1);
-
-    CollectionIfElement second = list.elements[1];
-    BooleanLiteral condition = second.condition;
-    expect(condition.value, isTrue);
-    SpreadElement thenElement = second.thenElement;
-    expect(thenElement.spreadOperator.lexeme, '...');
-    SpreadElement elseElement = second.elseElement;
-    expect(elseElement.spreadOperator.lexeme, '...?');
-  }
-
   void test_listLiteral_spread() {
     ListLiteral2 list = parseCollectionLiteral('[1, ...[2]]');
     expect(list.elements, hasLength(2));
@@ -330,7 +330,7 @@
     IntegerLiteral firstValue = first.value;
     expect(firstValue.value, 7);
 
-    MapForElement second = map.entries[1];
+    ForElement second = map.entries[1];
     expect(second.awaitKeyword, isNotNull);
     expect(second.forKeyword.isKeyword, isTrue);
     expect(second.leftParenthesis.lexeme, '(');
@@ -352,7 +352,7 @@
     IntegerLiteral firstValue = first.value;
     expect(firstValue.value, 7);
 
-    MapForElement second = map.entries[1];
+    ForElement second = map.entries[1];
     expect(second.awaitKeyword, isNotNull);
     expect(second.forKeyword.isKeyword, isTrue);
     expect(second.leftParenthesis.lexeme, '(');
@@ -364,7 +364,7 @@
     SimpleIdentifier iterable = forLoopParts.iterable;
     expect(iterable.name, 'list');
 
-    MapIfElement body = second.body;
+    IfElement body = second.body;
     SimpleIdentifier condition = body.condition;
     expect(condition.name, 'c');
     MapLiteralEntry thenElement = body.thenElement;
@@ -380,7 +380,7 @@
     IntegerLiteral firstValue = first.value;
     expect(firstValue.value, 7);
 
-    MapForElement second = map.entries[1];
+    ForElement second = map.entries[1];
     expect(second.awaitKeyword, isNull);
     expect(second.forKeyword.isKeyword, isTrue);
     expect(second.leftParenthesis.lexeme, '(');
@@ -404,7 +404,7 @@
     IntegerLiteral firstValue = first.value;
     expect(firstValue.value, 1);
 
-    MapIfElement second = map.entries[1];
+    IfElement second = map.entries[1];
     BooleanLiteral condition = second.condition;
     expect(condition.value, isTrue);
     MapLiteralEntry thenElement = second.thenElement;
@@ -420,7 +420,7 @@
     IntegerLiteral firstValue = first.value;
     expect(firstValue.value, 1);
 
-    MapIfElement second = map.entries[1];
+    IfElement second = map.entries[1];
     BooleanLiteral condition = second.condition;
     expect(condition.value, isTrue);
     MapLiteralEntry thenElement = second.thenElement;
@@ -439,14 +439,14 @@
     IntegerLiteral firstValue = first.value;
     expect(firstValue.value, 1);
 
-    MapIfElement second = map.entries[1];
+    IfElement second = map.entries[1];
     BooleanLiteral condition = second.condition;
     expect(condition.value, isTrue);
     MapLiteralEntry thenElement = second.thenElement;
     IntegerLiteral thenElementValue = thenElement.value;
     expect(thenElementValue.value, 4);
 
-    MapForElement elseElement = second.elseElement;
+    ForElement elseElement = second.elseElement;
     ForEachPartsWithIdentifier forLoopParts = elseElement.forLoopParts;
     expect(forLoopParts.identifier.name, 'c');
 
@@ -455,6 +455,28 @@
     expect(bodyValue.value, 6);
   }
 
+  void test_mapLiteral_ifElseSpread() {
+    MapLiteral2 map =
+        parseCollectionLiteral('{1:7, if (true) ...{2:4} else ...?{5:6}}');
+    expect(map.entries, hasLength(2));
+    MapLiteralEntry first = map.entries[0];
+    IntegerLiteral firstValue = first.value;
+    expect(firstValue.value, 7);
+
+    IfElement second = map.entries[1];
+    BooleanLiteral condition = second.condition;
+    expect(condition.value, isTrue);
+    SpreadElement thenElement = second.thenElement;
+    expect(thenElement.spreadOperator.lexeme, '...');
+    SpreadElement elseElement = second.elseElement;
+    expect(elseElement.spreadOperator.lexeme, '...?');
+    MapLiteral2 elseElementExpression = elseElement.expression;
+    expect(elseElementExpression.entries, hasLength(1));
+    MapLiteralEntry entry = elseElementExpression.entries[0];
+    IntegerLiteral entryValue = entry.value;
+    expect(entryValue.value, 6);
+  }
+
   void test_mapLiteral_ifFor() {
     MapLiteral2 map =
         parseCollectionLiteral('{1:1, if (true) for (a in b) 2:4}');
@@ -463,11 +485,11 @@
     IntegerLiteral firstValue = first.value;
     expect(firstValue.value, 1);
 
-    MapIfElement second = map.entries[1];
+    IfElement second = map.entries[1];
     BooleanLiteral condition = second.condition;
     expect(condition.value, isTrue);
 
-    MapForElement thenElement = second.thenElement;
+    ForElement thenElement = second.thenElement;
     ForEachPartsWithIdentifier forLoopParts = thenElement.forLoopParts;
     expect(forLoopParts.identifier.name, 'a');
 
@@ -484,7 +506,7 @@
     IntegerLiteral firstValue = first.value;
     expect(firstValue.value, 1);
 
-    MapIfElement second = map.entries[1];
+    IfElement second = map.entries[1];
     BooleanLiteral condition = second.condition;
     expect(condition.value, isTrue);
     SpreadElement thenElement = second.thenElement;
@@ -492,28 +514,6 @@
     expect(second.elseElement, isNull);
   }
 
-  void test_mapLiteral_ifElseSpread() {
-    MapLiteral2 map =
-        parseCollectionLiteral('{1:7, if (true) ...{2:4} else ...?{5:6}}');
-    expect(map.entries, hasLength(2));
-    MapLiteralEntry first = map.entries[0];
-    IntegerLiteral firstValue = first.value;
-    expect(firstValue.value, 7);
-
-    MapIfElement second = map.entries[1];
-    BooleanLiteral condition = second.condition;
-    expect(condition.value, isTrue);
-    SpreadElement thenElement = second.thenElement;
-    expect(thenElement.spreadOperator.lexeme, '...');
-    SpreadElement elseElement = second.elseElement;
-    expect(elseElement.spreadOperator.lexeme, '...?');
-    MapLiteral2 elseElementExpression = elseElement.expression;
-    expect(elseElementExpression.entries, hasLength(1));
-    MapLiteralEntry entry = elseElementExpression.entries[0];
-    IntegerLiteral entryValue = entry.value;
-    expect(entryValue.value, 6);
-  }
-
   void test_mapLiteral_spread() {
     MapLiteral2 map = parseCollectionLiteral('{1: 2, ...{3: 4}}');
     expect(map.constKeyword, isNull);
@@ -526,6 +526,30 @@
     expect(spreadExpression.entries, hasLength(1));
   }
 
+  void test_mapLiteral_spread2_typed() {
+    MapLiteral2 map = parseCollectionLiteral('<int, int>{1: 2, ...{3: 4}}');
+    expect(map.constKeyword, isNull);
+    expect(map.typeArguments.arguments, hasLength(2));
+    expect(map.entries, hasLength(2));
+
+    SpreadElement element = map.entries[1];
+    expect(element.spreadOperator.lexeme, '...');
+    MapLiteral2 spreadExpression = element.expression;
+    expect(spreadExpression.entries, hasLength(1));
+  }
+
+  void test_mapLiteral_spread_typed() {
+    MapLiteral2 map = parseCollectionLiteral('<int, int>{...{3: 4}}');
+    expect(map.constKeyword, isNull);
+    expect(map.typeArguments.arguments, hasLength(2));
+    expect(map.entries, hasLength(1));
+
+    SpreadElement element = map.entries[0];
+    expect(element.spreadOperator.lexeme, '...');
+    MapLiteral2 spreadExpression = element.expression;
+    expect(spreadExpression.entries, hasLength(1));
+  }
+
   void test_mapLiteral_spreadQ() {
     MapLiteral2 map = parseCollectionLiteral('{1: 2, ...?{3: 4}}');
     expect(map.constKeyword, isNull);
@@ -538,14 +562,14 @@
     expect(spreadExpression.entries, hasLength(1));
   }
 
-  void test_mapLiteral_spread_typed() {
-    MapLiteral2 map = parseCollectionLiteral('<int, int>{...{3: 4}}');
+  void test_mapLiteral_spreadQ2_typed() {
+    MapLiteral2 map = parseCollectionLiteral('<int, int>{1: 2, ...?{3: 4}}');
     expect(map.constKeyword, isNull);
     expect(map.typeArguments.arguments, hasLength(2));
-    expect(map.entries, hasLength(1));
+    expect(map.entries, hasLength(2));
 
-    SpreadElement element = map.entries[0];
-    expect(element.spreadOperator.lexeme, '...');
+    SpreadElement element = map.entries[1];
+    expect(element.spreadOperator.lexeme, '...?');
     MapLiteral2 spreadExpression = element.expression;
     expect(spreadExpression.entries, hasLength(1));
   }
@@ -562,37 +586,13 @@
     expect(spreadExpression.entries, hasLength(1));
   }
 
-  void test_mapLiteral_spread2_typed() {
-    MapLiteral2 map = parseCollectionLiteral('<int, int>{1: 2, ...{3: 4}}');
-    expect(map.constKeyword, isNull);
-    expect(map.typeArguments.arguments, hasLength(2));
-    expect(map.entries, hasLength(2));
-
-    SpreadElement element = map.entries[1];
-    expect(element.spreadOperator.lexeme, '...');
-    MapLiteral2 spreadExpression = element.expression;
-    expect(spreadExpression.entries, hasLength(1));
-  }
-
-  void test_mapLiteral_spreadQ2_typed() {
-    MapLiteral2 map = parseCollectionLiteral('<int, int>{1: 2, ...?{3: 4}}');
-    expect(map.constKeyword, isNull);
-    expect(map.typeArguments.arguments, hasLength(2));
-    expect(map.entries, hasLength(2));
-
-    SpreadElement element = map.entries[1];
-    expect(element.spreadOperator.lexeme, '...?');
-    MapLiteral2 spreadExpression = element.expression;
-    expect(spreadExpression.entries, hasLength(1));
-  }
-
   void test_setLiteral_if() {
     SetLiteral2 setLiteral = parseCollectionLiteral('{1, if (true) 2}');
     expect(setLiteral.elements, hasLength(2));
     IntegerLiteral first = setLiteral.elements[0];
     expect(first.value, 1);
 
-    CollectionIfElement second = setLiteral.elements[1];
+    IfElement second = setLiteral.elements[1];
     BooleanLiteral condition = second.condition;
     expect(condition.value, isTrue);
     IntegerLiteral thenElement = second.thenElement;
@@ -606,7 +606,7 @@
     IntegerLiteral first = setLiteral.elements[0];
     expect(first.value, 1);
 
-    CollectionIfElement second = setLiteral.elements[1];
+    IfElement second = setLiteral.elements[1];
     BooleanLiteral condition = second.condition;
     expect(condition.value, isTrue);
     IntegerLiteral thenElement = second.thenElement;
@@ -615,20 +615,6 @@
     expect(elseElement.value, 5);
   }
 
-  void test_setLiteral_ifSpread() {
-    SetLiteral2 setLiteral = parseCollectionLiteral('{1, if (true) ...[2]}');
-    expect(setLiteral.elements, hasLength(2));
-    IntegerLiteral first = setLiteral.elements[0];
-    expect(first.value, 1);
-
-    CollectionIfElement second = setLiteral.elements[1];
-    BooleanLiteral condition = second.condition;
-    expect(condition.value, isTrue);
-    SpreadElement thenElement = second.thenElement;
-    expect(thenElement.spreadOperator.lexeme, '...');
-    expect(second.elseElement, isNull);
-  }
-
   void test_setLiteral_ifElseSpread() {
     SetLiteral2 setLiteral =
         parseCollectionLiteral('{1, if (true) ...{2} else ...?[5]}');
@@ -636,7 +622,7 @@
     IntegerLiteral first = setLiteral.elements[0];
     expect(first.value, 1);
 
-    CollectionIfElement second = setLiteral.elements[1];
+    IfElement second = setLiteral.elements[1];
     BooleanLiteral condition = second.condition;
     expect(condition.value, isTrue);
     SpreadElement thenElement = second.thenElement;
@@ -649,6 +635,20 @@
     expect(elseExpression.elements, hasLength(1));
   }
 
+  void test_setLiteral_ifSpread() {
+    SetLiteral2 setLiteral = parseCollectionLiteral('{1, if (true) ...[2]}');
+    expect(setLiteral.elements, hasLength(2));
+    IntegerLiteral first = setLiteral.elements[0];
+    expect(first.value, 1);
+
+    IfElement second = setLiteral.elements[1];
+    BooleanLiteral condition = second.condition;
+    expect(condition.value, isTrue);
+    SpreadElement thenElement = second.thenElement;
+    expect(thenElement.spreadOperator.lexeme, '...');
+    expect(second.elseElement, isNull);
+  }
+
   void test_setLiteral_spread2() {
     SetLiteral2 set = parseCollectionLiteral('{3, ...[4]}');
     expect(set.constKeyword, isNull);
@@ -864,24 +864,6 @@
 @reflectiveTest
 class ExpressionParserTest_Fasta extends FastaParserTestCase
     with ExpressionParserTestMixin {
-  @override
-  @failingTest
-  void test_parseUnaryExpression_decrement_super() {
-    // TODO(danrubel) Reports a different error and different token stream.
-    // Expected: TokenType:<MINUS>
-    //   Actual: TokenType:<MINUS_MINUS>
-    super.test_parseUnaryExpression_decrement_super();
-  }
-
-  @override
-  @failingTest
-  void test_parseUnaryExpression_decrement_super_withComment() {
-    // TODO(danrubel) Reports a different error and different token stream.
-    // Expected: TokenType:<MINUS>
-    //   Actual: TokenType:<MINUS_MINUS>
-    super.test_parseUnaryExpression_decrement_super_withComment();
-  }
-
   void test_listLiteral_spread() {
     // TODO(danrubel): Remove this once spread_collections is enabled by default
     ListLiteral list = parseExpression('[1, ...[2]]', errors: [
@@ -983,13 +965,13 @@
     expect(map.entries, hasLength(1));
   }
 
-  void test_mapLiteral_spreadQ() {
+  void test_mapLiteral_spread2_typed() {
     // TODO(danrubel): Remove this once spread_collections is enabled by default
-    MapLiteral map = parseExpression('{1: 2, ...?{3: 4}}',
+    MapLiteral map = parseExpression('<int, int>{1: 2, ...{3: 4}}',
         parseSetLiterals: true,
-        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 7, 4)]);
+        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 17, 3)]);
     expect(map.constKeyword, isNull);
-    expect(map.typeArguments, isNull);
+    expect(map.typeArguments.arguments, hasLength(2));
     expect(map.entries, hasLength(1));
   }
 
@@ -1003,23 +985,13 @@
     expect(map.entries, hasLength(0));
   }
 
-  void test_mapLiteral_spreadQ_typed() {
+  void test_mapLiteral_spreadQ() {
     // TODO(danrubel): Remove this once spread_collections is enabled by default
-    MapLiteral map = parseExpression('<int, int>{...?{3: 4}}',
+    MapLiteral map = parseExpression('{1: 2, ...?{3: 4}}',
         parseSetLiterals: true,
-        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 11, 4)]);
+        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 7, 4)]);
     expect(map.constKeyword, isNull);
-    expect(map.typeArguments.arguments, hasLength(2));
-    expect(map.entries, hasLength(0));
-  }
-
-  void test_mapLiteral_spread2_typed() {
-    // TODO(danrubel): Remove this once spread_collections is enabled by default
-    MapLiteral map = parseExpression('<int, int>{1: 2, ...{3: 4}}',
-        parseSetLiterals: true,
-        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 17, 3)]);
-    expect(map.constKeyword, isNull);
-    expect(map.typeArguments.arguments, hasLength(2));
+    expect(map.typeArguments, isNull);
     expect(map.entries, hasLength(1));
   }
 
@@ -1033,6 +1005,34 @@
     expect(map.entries, hasLength(1));
   }
 
+  void test_mapLiteral_spreadQ_typed() {
+    // TODO(danrubel): Remove this once spread_collections is enabled by default
+    MapLiteral map = parseExpression('<int, int>{...?{3: 4}}',
+        parseSetLiterals: true,
+        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 11, 4)]);
+    expect(map.constKeyword, isNull);
+    expect(map.typeArguments.arguments, hasLength(2));
+    expect(map.entries, hasLength(0));
+  }
+
+  @override
+  @failingTest
+  void test_parseUnaryExpression_decrement_super() {
+    // TODO(danrubel) Reports a different error and different token stream.
+    // Expected: TokenType:<MINUS>
+    //   Actual: TokenType:<MINUS_MINUS>
+    super.test_parseUnaryExpression_decrement_super();
+  }
+
+  @override
+  @failingTest
+  void test_parseUnaryExpression_decrement_super_withComment() {
+    // TODO(danrubel) Reports a different error and different token stream.
+    // Expected: TokenType:<MINUS>
+    //   Actual: TokenType:<MINUS_MINUS>
+    super.test_parseUnaryExpression_decrement_super_withComment();
+  }
+
   void test_setLiteral() {
     SetLiteral set = parseExpression('{3}', parseSetLiterals: true);
     expect(set.constKeyword, isNull);
@@ -1704,6 +1704,172 @@
     with FormalParameterParserTestMixin {}
 
 /**
+ * Tests of the fasta parser based on [ComplexParserTestMixin].
+ */
+@reflectiveTest
+class NNBDParserTest_Fasta extends FastaParserTestCase {
+  CompilationUnit parseNNBDCompilationUnit(String code,
+      {List<ExpectedError> errors}) {
+    createParser('''
+@pragma('analyzer:non-nullable') library nnbd.parser.test;
+$code
+''');
+    _parserProxy.astBuilder.enableNonNullable = true;
+    CompilationUnit unit = _parserProxy.parseCompilationUnit2();
+    assertErrors(errors: errors);
+    return unit;
+  }
+
+  void test_assignment_complex() {
+    parseNNBDCompilationUnit('D? foo(X? x) { X? x1; X? x2 = x + bar(7); }');
+  }
+
+  void test_assignment_simple() {
+    parseNNBDCompilationUnit('D? foo(X? x) { X? x1; X? x2 = x; }');
+  }
+
+  void test_binary_expression_statement() {
+    final unit = parseNNBDCompilationUnit('D? foo(X? x) { X ?? x2; }');
+    FunctionDeclaration funct = unit.declarations[0];
+    BlockFunctionBody body = funct.functionExpression.body;
+    ExpressionStatement statement = body.block.statements[0];
+    BinaryExpression expression = statement.expression;
+    SimpleIdentifier lhs = expression.leftOperand;
+    expect(lhs.name, 'X');
+    expect(expression.operator.lexeme, '??');
+    SimpleIdentifier rhs = expression.rightOperand;
+    expect(rhs.name, 'x2');
+  }
+
+  void test_conditional() {
+    parseNNBDCompilationUnit('D? foo(X? x) { X ? 7 : y; }');
+  }
+
+  void test_conditional_complex() {
+    parseNNBDCompilationUnit('D? foo(X? x) { X ? x2 = x + bar(7) : y; }');
+  }
+
+  void test_conditional_error() {
+    parseNNBDCompilationUnit('D? foo(X? x) { X ? ? x2 = x + bar(7) : y; }',
+        errors: [
+          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 78, 1),
+          expectedError(ParserErrorCode.EXPECTED_TOKEN, 99, 1),
+          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 99, 1),
+        ]);
+  }
+
+  void test_conditional_simple() {
+    parseNNBDCompilationUnit('D? foo(X? x) { X ? x2 = x : y; }');
+  }
+
+  void test_enableNonNullable_false() {
+    parseCompilationUnit('main() { x is String? ? (x + y) : z; }',
+        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 20, 1)]);
+  }
+
+  void test_for() {
+    parseNNBDCompilationUnit('main() { for(int x = 0; x < 7; ++x) { } }');
+  }
+
+  void test_for_conditional() {
+    parseNNBDCompilationUnit(
+        'main() { for(x ? y = 7 : y = 8; y < 10; ++y) { } }');
+  }
+
+  void test_for_nullable() {
+    parseNNBDCompilationUnit('main() { for(int? x = 0; x < 7; ++x) { } }');
+  }
+
+  void test_foreach() {
+    parseNNBDCompilationUnit('main() { for(int x in [7]) { } }');
+  }
+
+  void test_foreach_nullable() {
+    parseNNBDCompilationUnit('main() { for(int? x in [7, null]) { } }');
+  }
+
+  void test_gft_nullable() {
+    parseNNBDCompilationUnit('main() { C? Function() x = 7; }');
+  }
+
+  void test_gft_nullable_1() {
+    parseNNBDCompilationUnit('main() { C Function()? x = 7; }');
+  }
+
+  void test_gft_nullable_2() {
+    parseNNBDCompilationUnit('main() { C? Function()? x = 7; }');
+  }
+
+  void test_gft_nullable_3() {
+    parseNNBDCompilationUnit('main() { C? Function()? Function()? x = 7; }');
+  }
+
+  void test_gft_nullable_prefixed() {
+    parseNNBDCompilationUnit('main() { C.a? Function()? x = 7; }');
+  }
+
+  void test_is_nullable() {
+    CompilationUnit unit =
+        parseNNBDCompilationUnit('main() { x is String? ? (x + y) : z; }');
+    FunctionDeclaration function = unit.declarations[0];
+    BlockFunctionBody body = function.functionExpression.body;
+    ExpressionStatement statement = body.block.statements[0];
+    ConditionalExpression expression = statement.expression;
+
+    IsExpression condition = expression.condition;
+    expect((condition.type as NamedType).question, isNotNull);
+    Expression thenExpression = expression.thenExpression;
+    expect(thenExpression, isParenthesizedExpression);
+    Expression elseExpression = expression.elseExpression;
+    expect(elseExpression, isSimpleIdentifier);
+  }
+
+  void test_is_nullable_parenthesis() {
+    CompilationUnit unit =
+        parseNNBDCompilationUnit('main() { (x is String?) ? (x + y) : z; }');
+    FunctionDeclaration function = unit.declarations[0];
+    BlockFunctionBody body = function.functionExpression.body;
+    ExpressionStatement statement = body.block.statements[0];
+    ConditionalExpression expression = statement.expression;
+
+    ParenthesizedExpression condition = expression.condition;
+    IsExpression isExpression = condition.expression;
+    expect((isExpression.type as NamedType).question, isNotNull);
+    Expression thenExpression = expression.thenExpression;
+    expect(thenExpression, isParenthesizedExpression);
+    Expression elseExpression = expression.elseExpression;
+    expect(elseExpression, isSimpleIdentifier);
+  }
+
+  void test_pragma_missing() {
+    createParser("library foo;");
+    _parserProxy.astBuilder.enableNonNullable = true;
+    CompilationUnitImpl unit = _parserProxy.parseCompilationUnit2();
+    expect(unit.hasPragmaAnalyzerNonNullable, false);
+  }
+
+  void test_pragma_non_nullable() {
+    createParser("@pragma('analyzer:non-nullable') library foo;");
+    _parserProxy.astBuilder.enableNonNullable = true;
+    CompilationUnitImpl unit = _parserProxy.parseCompilationUnit2();
+    expect(unit.hasPragmaAnalyzerNonNullable, true);
+  }
+
+  void test_pragma_non_nullable_not_enabled() {
+    createParser("@pragma('analyzer:non-nullable') library foo;");
+    CompilationUnitImpl unit = _parserProxy.parseCompilationUnit2();
+    expect(unit.hasPragmaAnalyzerNonNullable, false);
+  }
+
+  void test_pragma_other() {
+    createParser("@pragma('analyzer:foo') library foo;");
+    _parserProxy.astBuilder.enableNonNullable = true;
+    CompilationUnitImpl unit = _parserProxy.parseCompilationUnit2();
+    expect(unit.hasPragmaAnalyzerNonNullable, false);
+  }
+}
+
+/**
  * Proxy implementation of the analyzer parser, implemented in terms of the
  * Fasta parser.
  *
@@ -2609,169 +2775,3 @@
     expectCommentText(declaration.documentationComment, '/// Doc');
   }
 }
-
-/**
- * Tests of the fasta parser based on [ComplexParserTestMixin].
- */
-@reflectiveTest
-class NNBDParserTest_Fasta extends FastaParserTestCase {
-  CompilationUnit parseNNBDCompilationUnit(String code,
-      {List<ExpectedError> errors}) {
-    createParser('''
-@pragma('analyzer:non-nullable') library nnbd.parser.test;
-$code
-''');
-    _parserProxy.astBuilder.enableNonNullable = true;
-    CompilationUnit unit = _parserProxy.parseCompilationUnit2();
-    assertErrors(errors: errors);
-    return unit;
-  }
-
-  void test_assignment_complex() {
-    parseNNBDCompilationUnit('D? foo(X? x) { X? x1; X? x2 = x + bar(7); }');
-  }
-
-  void test_assignment_simple() {
-    parseNNBDCompilationUnit('D? foo(X? x) { X? x1; X? x2 = x; }');
-  }
-
-  void test_gft_nullable() {
-    parseNNBDCompilationUnit('main() { C? Function() x = 7; }');
-  }
-
-  void test_gft_nullable_1() {
-    parseNNBDCompilationUnit('main() { C Function()? x = 7; }');
-  }
-
-  void test_gft_nullable_2() {
-    parseNNBDCompilationUnit('main() { C? Function()? x = 7; }');
-  }
-
-  void test_gft_nullable_3() {
-    parseNNBDCompilationUnit('main() { C? Function()? Function()? x = 7; }');
-  }
-
-  void test_gft_nullable_prefixed() {
-    parseNNBDCompilationUnit('main() { C.a? Function()? x = 7; }');
-  }
-
-  void test_binary_expression_statement() {
-    final unit = parseNNBDCompilationUnit('D? foo(X? x) { X ?? x2; }');
-    FunctionDeclaration funct = unit.declarations[0];
-    BlockFunctionBody body = funct.functionExpression.body;
-    ExpressionStatement statement = body.block.statements[0];
-    BinaryExpression expression = statement.expression;
-    SimpleIdentifier lhs = expression.leftOperand;
-    expect(lhs.name, 'X');
-    expect(expression.operator.lexeme, '??');
-    SimpleIdentifier rhs = expression.rightOperand;
-    expect(rhs.name, 'x2');
-  }
-
-  void test_conditional() {
-    parseNNBDCompilationUnit('D? foo(X? x) { X ? 7 : y; }');
-  }
-
-  void test_conditional_complex() {
-    parseNNBDCompilationUnit('D? foo(X? x) { X ? x2 = x + bar(7) : y; }');
-  }
-
-  void test_conditional_error() {
-    parseNNBDCompilationUnit('D? foo(X? x) { X ? ? x2 = x + bar(7) : y; }',
-        errors: [
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 78, 1),
-          expectedError(ParserErrorCode.EXPECTED_TOKEN, 99, 1),
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 99, 1),
-        ]);
-  }
-
-  void test_conditional_simple() {
-    parseNNBDCompilationUnit('D? foo(X? x) { X ? x2 = x : y; }');
-  }
-
-  void test_for() {
-    parseNNBDCompilationUnit('main() { for(int x = 0; x < 7; ++x) { } }');
-  }
-
-  void test_for_conditional() {
-    parseNNBDCompilationUnit(
-        'main() { for(x ? y = 7 : y = 8; y < 10; ++y) { } }');
-  }
-
-  void test_for_nullable() {
-    parseNNBDCompilationUnit('main() { for(int? x = 0; x < 7; ++x) { } }');
-  }
-
-  void test_foreach() {
-    parseNNBDCompilationUnit('main() { for(int x in [7]) { } }');
-  }
-
-  void test_foreach_nullable() {
-    parseNNBDCompilationUnit('main() { for(int? x in [7, null]) { } }');
-  }
-
-  void test_is_nullable() {
-    CompilationUnit unit =
-        parseNNBDCompilationUnit('main() { x is String? ? (x + y) : z; }');
-    FunctionDeclaration function = unit.declarations[0];
-    BlockFunctionBody body = function.functionExpression.body;
-    ExpressionStatement statement = body.block.statements[0];
-    ConditionalExpression expression = statement.expression;
-
-    IsExpression condition = expression.condition;
-    expect((condition.type as NamedType).question, isNotNull);
-    Expression thenExpression = expression.thenExpression;
-    expect(thenExpression, isParenthesizedExpression);
-    Expression elseExpression = expression.elseExpression;
-    expect(elseExpression, isSimpleIdentifier);
-  }
-
-  void test_is_nullable_parenthesis() {
-    CompilationUnit unit =
-        parseNNBDCompilationUnit('main() { (x is String?) ? (x + y) : z; }');
-    FunctionDeclaration function = unit.declarations[0];
-    BlockFunctionBody body = function.functionExpression.body;
-    ExpressionStatement statement = body.block.statements[0];
-    ConditionalExpression expression = statement.expression;
-
-    ParenthesizedExpression condition = expression.condition;
-    IsExpression isExpression = condition.expression;
-    expect((isExpression.type as NamedType).question, isNotNull);
-    Expression thenExpression = expression.thenExpression;
-    expect(thenExpression, isParenthesizedExpression);
-    Expression elseExpression = expression.elseExpression;
-    expect(elseExpression, isSimpleIdentifier);
-  }
-
-  void test_pragma_missing() {
-    createParser("library foo;");
-    _parserProxy.astBuilder.enableNonNullable = true;
-    CompilationUnitImpl unit = _parserProxy.parseCompilationUnit2();
-    expect(unit.hasPragmaAnalyzerNonNullable, false);
-  }
-
-  void test_pragma_non_nullable() {
-    createParser("@pragma('analyzer:non-nullable') library foo;");
-    _parserProxy.astBuilder.enableNonNullable = true;
-    CompilationUnitImpl unit = _parserProxy.parseCompilationUnit2();
-    expect(unit.hasPragmaAnalyzerNonNullable, true);
-  }
-
-  void test_pragma_non_nullable_not_enabled() {
-    createParser("@pragma('analyzer:non-nullable') library foo;");
-    CompilationUnitImpl unit = _parserProxy.parseCompilationUnit2();
-    expect(unit.hasPragmaAnalyzerNonNullable, false);
-  }
-
-  void test_pragma_other() {
-    createParser("@pragma('analyzer:foo') library foo;");
-    _parserProxy.astBuilder.enableNonNullable = true;
-    CompilationUnitImpl unit = _parserProxy.parseCompilationUnit2();
-    expect(unit.hasPragmaAnalyzerNonNullable, false);
-  }
-
-  void test_enableNonNullable_false() {
-    parseCompilationUnit('main() { x is String? ? (x + y) : z; }',
-        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 20, 1)]);
-  }
-}
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 9d5b456..faf4a1c 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -1930,46 +1930,6 @@
     expect(expression.condition, isBinaryExpression);
   }
 
-  void test_conditionalExpression_precedence_withAssignment() {
-    ExpressionStatement statement = parseStatement('b ? c = true : g();');
-    ConditionalExpression expression = statement.expression;
-    expect(expression.condition, new TypeMatcher<SimpleIdentifier>());
-    expect(expression.thenExpression, new TypeMatcher<AssignmentExpression>());
-  }
-
-  void test_conditionalExpression_precedence_withAssignment2() {
-    ExpressionStatement statement = parseStatement('b.x ? c = true : g();');
-    ConditionalExpression expression = statement.expression;
-    expect(expression.condition, new TypeMatcher<PrefixedIdentifier>());
-    expect(expression.thenExpression, new TypeMatcher<AssignmentExpression>());
-  }
-
-  void test_conditionalExpression_prefixedValue() {
-    ExpressionStatement statement = parseStatement('a.b ? y : z;');
-    ConditionalExpression expression = statement.expression;
-    expect(expression.condition, new TypeMatcher<PrefixedIdentifier>());
-    expect(expression.thenExpression, new TypeMatcher<SimpleIdentifier>());
-  }
-
-  void test_conditionalExpression_prefixedValue2() {
-    ExpressionStatement statement = parseStatement('a.b ? x.y : z;');
-    ConditionalExpression expression = statement.expression;
-    expect(expression.condition, new TypeMatcher<PrefixedIdentifier>());
-    expect(expression.thenExpression, new TypeMatcher<PrefixedIdentifier>());
-  }
-
-  void test_conditionalExpression_precedence_prefixedNullableType_is() {
-    ExpressionStatement statement = parseStatement('x is p.A ? (x + y) : z;');
-    ConditionalExpression expression = statement.expression;
-
-    Expression condition = expression.condition;
-    expect(condition, new TypeMatcher<IsExpression>());
-    Expression thenExpression = expression.thenExpression;
-    expect(thenExpression, new TypeMatcher<ParenthesizedExpression>());
-    Expression elseExpression = expression.elseExpression;
-    expect(elseExpression, new TypeMatcher<SimpleIdentifier>());
-  }
-
   void test_conditionalExpression_precedence_nullableType_as() {
     ExpressionStatement statement = parseStatement('x as bool ? (x + y) : z;');
     ConditionalExpression expression = statement.expression;
@@ -2029,6 +1989,46 @@
     expect(elseExpression, new TypeMatcher<SimpleIdentifier>());
   }
 
+  void test_conditionalExpression_precedence_prefixedNullableType_is() {
+    ExpressionStatement statement = parseStatement('x is p.A ? (x + y) : z;');
+    ConditionalExpression expression = statement.expression;
+
+    Expression condition = expression.condition;
+    expect(condition, new TypeMatcher<IsExpression>());
+    Expression thenExpression = expression.thenExpression;
+    expect(thenExpression, new TypeMatcher<ParenthesizedExpression>());
+    Expression elseExpression = expression.elseExpression;
+    expect(elseExpression, new TypeMatcher<SimpleIdentifier>());
+  }
+
+  void test_conditionalExpression_precedence_withAssignment() {
+    ExpressionStatement statement = parseStatement('b ? c = true : g();');
+    ConditionalExpression expression = statement.expression;
+    expect(expression.condition, new TypeMatcher<SimpleIdentifier>());
+    expect(expression.thenExpression, new TypeMatcher<AssignmentExpression>());
+  }
+
+  void test_conditionalExpression_precedence_withAssignment2() {
+    ExpressionStatement statement = parseStatement('b.x ? c = true : g();');
+    ConditionalExpression expression = statement.expression;
+    expect(expression.condition, new TypeMatcher<PrefixedIdentifier>());
+    expect(expression.thenExpression, new TypeMatcher<AssignmentExpression>());
+  }
+
+  void test_conditionalExpression_prefixedValue() {
+    ExpressionStatement statement = parseStatement('a.b ? y : z;');
+    ConditionalExpression expression = statement.expression;
+    expect(expression.condition, new TypeMatcher<PrefixedIdentifier>());
+    expect(expression.thenExpression, new TypeMatcher<SimpleIdentifier>());
+  }
+
+  void test_conditionalExpression_prefixedValue2() {
+    ExpressionStatement statement = parseStatement('a.b ? x.y : z;');
+    ConditionalExpression expression = statement.expression;
+    expect(expression.condition, new TypeMatcher<PrefixedIdentifier>());
+    expect(expression.thenExpression, new TypeMatcher<PrefixedIdentifier>());
+  }
+
   void test_constructor_initializer_withParenthesizedExpression() {
     CompilationUnit unit = parseCompilationUnit(r'''
 class C {
diff --git a/pkg/analyzer/test/src/dart/ast/utilities_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
index ddf728d..1a9032b 100644
--- a/pkg/analyzer/test/src/dart/ast/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
@@ -225,45 +225,6 @@
     expect(toNode.staticType, same(staticType));
   }
 
-  void test_visitCollectionForElement() {
-    CollectionForElement createNode() => astFactory.collectionForElement(
-        forLoopParts: astFactory.forEachPartsWithIdentifier(
-            identifier: AstTestFactory.identifier3('a'),
-            iterable: AstTestFactory.identifier3('b')),
-        body: AstTestFactory.identifier3('c'));
-
-    DartType typeC = ElementFactory.classElement2("C").type;
-
-    CollectionForElement fromNode = createNode();
-    (fromNode.body as SimpleIdentifier).staticType = typeC;
-
-    CollectionForElement toNode = createNode();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect((toNode.body as SimpleIdentifier).staticType, same(typeC));
-  }
-
-  void test_visitCollectionIfElement() {
-    CollectionIfElement createNode() => astFactory.collectionIfElement(
-        condition: AstTestFactory.identifier3('a'),
-        thenElement: AstTestFactory.identifier3('b'),
-        elseElement: AstTestFactory.identifier3('c'));
-
-    DartType typeA = ElementFactory.classElement2("A").type;
-    DartType typeB = ElementFactory.classElement2("B").type;
-    DartType typeC = ElementFactory.classElement2("C").type;
-
-    CollectionIfElement fromNode = createNode();
-    (fromNode.condition as SimpleIdentifier).staticType = typeA;
-    (fromNode.thenElement as SimpleIdentifier).staticType = typeB;
-    (fromNode.elseElement as SimpleIdentifier).staticType = typeC;
-
-    CollectionIfElement toNode = createNode();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect(toNode.condition.staticType, same(typeA));
-    expect((toNode.thenElement as SimpleIdentifier).staticType, same(typeB));
-    expect((toNode.elseElement as SimpleIdentifier).staticType, same(typeC));
-  }
-
   void test_visitCompilationUnit() {
     CompilationUnit fromNode = AstTestFactory.compilationUnit();
     CompilationUnitElement element = new CompilationUnitElementImpl();
@@ -373,6 +334,23 @@
     expect((toNode.iterable as SimpleIdentifier).staticType, same(typeB));
   }
 
+  void test_visitForElement() {
+    ForElement createNode() => astFactory.forElement(
+        forLoopParts: astFactory.forEachPartsWithIdentifier(
+            identifier: AstTestFactory.identifier3('a'),
+            iterable: AstTestFactory.identifier3('b')),
+        body: AstTestFactory.identifier3('c'));
+
+    DartType typeC = ElementFactory.classElement2("C").type;
+
+    ForElement fromNode = createNode();
+    (fromNode.body as SimpleIdentifier).staticType = typeC;
+
+    ForElement toNode = createNode();
+    ResolutionCopier.copyResolutionData(fromNode, toNode);
+    expect((toNode.body as SimpleIdentifier).staticType, same(typeC));
+  }
+
   void test_visitForPartsWithDeclarations() {
     ForPartsWithDeclarations createNode() =>
         astFactory.forPartsWithDeclarations(
@@ -485,6 +463,28 @@
     expect(toNode.staticElement, same(staticElement));
   }
 
+  void test_visitIfElement() {
+    IfElement createNode() => astFactory.ifElement(
+        condition: AstTestFactory.identifier3('a'),
+        thenElement: AstTestFactory.identifier3('b'),
+        elseElement: AstTestFactory.identifier3('c'));
+
+    DartType typeA = ElementFactory.classElement2("A").type;
+    DartType typeB = ElementFactory.classElement2("B").type;
+    DartType typeC = ElementFactory.classElement2("C").type;
+
+    IfElement fromNode = createNode();
+    (fromNode.condition as SimpleIdentifier).staticType = typeA;
+    (fromNode.thenElement as SimpleIdentifier).staticType = typeB;
+    (fromNode.elseElement as SimpleIdentifier).staticType = typeC;
+
+    IfElement toNode = createNode();
+    ResolutionCopier.copyResolutionData(fromNode, toNode);
+    expect(toNode.condition.staticType, same(typeA));
+    expect((toNode.thenElement as SimpleIdentifier).staticType, same(typeB));
+    expect((toNode.elseElement as SimpleIdentifier).staticType, same(typeC));
+  }
+
   void test_visitImportDirective() {
     ImportDirective fromNode =
         AstTestFactory.importDirective3("dart:uri", null);
@@ -590,55 +590,6 @@
     expect((toNode.elements[0] as SimpleIdentifier).staticType, same(typeB));
   }
 
-  void test_visitMapForElement() {
-    MapForElement createNode() => astFactory.mapForElement(
-        forLoopParts: astFactory.forEachPartsWithIdentifier(
-            identifier: AstTestFactory.identifier3('a'),
-            iterable: AstTestFactory.identifier3('b')),
-        body: AstTestFactory.mapLiteralEntry3('c', 'd'));
-
-    DartType typeC = ElementFactory.classElement2("C").type;
-
-    MapForElement fromNode = createNode();
-    (fromNode.body as MapLiteralEntry).key.staticType = typeC;
-
-    MapForElement toNode = createNode();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    expect((toNode.body as MapLiteralEntry).key.staticType, same(typeC));
-  }
-
-  void test_visitMapIfElement() {
-    MapIfElement createNode() => astFactory.mapIfElement(
-        condition: AstTestFactory.identifier3('a'),
-        thenElement: AstTestFactory.mapLiteralEntry3('b', 'c'),
-        elseElement: AstTestFactory.mapLiteralEntry3('d', 'e'));
-
-    DartType typeA = ElementFactory.classElement2("A").type;
-    DartType typeB = ElementFactory.classElement2("B").type;
-    DartType typeC = ElementFactory.classElement2("C").type;
-    DartType typeD = ElementFactory.classElement2("D").type;
-    DartType typeE = ElementFactory.classElement2("E").type;
-
-    MapIfElement fromNode = createNode();
-    MapLiteralEntry fromThen = fromNode.thenElement as MapLiteralEntry;
-    MapLiteralEntry fromElse = fromNode.elseElement as MapLiteralEntry;
-    (fromNode.condition as SimpleIdentifier).staticType = typeA;
-    (fromThen.key as SimpleStringLiteral).staticType = typeB;
-    (fromThen.value as SimpleStringLiteral).staticType = typeC;
-    (fromElse.key as SimpleStringLiteral).staticType = typeD;
-    (fromElse.value as SimpleStringLiteral).staticType = typeE;
-
-    MapIfElement toNode = createNode();
-    ResolutionCopier.copyResolutionData(fromNode, toNode);
-    MapLiteralEntry toThen = toNode.thenElement as MapLiteralEntry;
-    MapLiteralEntry toElse = toNode.elseElement as MapLiteralEntry;
-    expect(toNode.condition.staticType, same(typeA));
-    expect((toThen.key as SimpleStringLiteral).staticType, same(typeB));
-    expect((toThen.value as SimpleStringLiteral).staticType, same(typeC));
-    expect((toElse.key as SimpleStringLiteral).staticType, same(typeD));
-    expect((toElse.value as SimpleStringLiteral).staticType, same(typeE));
-  }
-
   void test_visitMapLiteral() {
     MapLiteral fromNode = AstTestFactory.mapLiteral2();
     DartType staticType = ElementFactory.classElement2("C").type;
@@ -1414,33 +1365,6 @@
     _assertSource("@deprecated class C = S with M1;", declaration);
   }
 
-  void test_visitCollectionForElement() {
-    _assertSource(
-        'for (e in l) 0',
-        astFactory.collectionForElement(
-            forLoopParts: astFactory.forEachPartsWithIdentifier(
-                identifier: AstTestFactory.identifier3('e'),
-                iterable: AstTestFactory.identifier3('l')),
-            body: AstTestFactory.integer(0)));
-  }
-
-  void test_visitCollectionIfElement_else() {
-    _assertSource(
-        'if (b) 1 else 0',
-        astFactory.collectionIfElement(
-            condition: AstTestFactory.identifier3('b'),
-            thenElement: AstTestFactory.integer(1),
-            elseElement: AstTestFactory.integer(0)));
-  }
-
-  void test_visitCollectionIfElement_then() {
-    _assertSource(
-        'if (b) 1',
-        astFactory.collectionIfElement(
-            condition: AstTestFactory.identifier3('b'),
-            thenElement: AstTestFactory.integer(1)));
-  }
-
   void test_visitComment() {
     _assertSource(
         "",
@@ -1924,6 +1848,16 @@
             AstTestFactory.block()));
   }
 
+  void test_visitForElement() {
+    _assertSource(
+        'for (e in l) 0',
+        astFactory.forElement(
+            forLoopParts: astFactory.forEachPartsWithIdentifier(
+                identifier: AstTestFactory.identifier3('e'),
+                iterable: AstTestFactory.identifier3('l')),
+            body: AstTestFactory.integer(0)));
+  }
+
   void test_visitFormalParameterList_empty() {
     _assertSource("()", AstTestFactory.formalParameterList());
   }
@@ -2460,6 +2394,23 @@
                 ]))));
   }
 
+  void test_visitIfElement_else() {
+    _assertSource(
+        'if (b) 1 else 0',
+        astFactory.ifElement(
+            condition: AstTestFactory.identifier3('b'),
+            thenElement: AstTestFactory.integer(1),
+            elseElement: AstTestFactory.integer(0)));
+  }
+
+  void test_visitIfElement_then() {
+    _assertSource(
+        'if (b) 1',
+        astFactory.ifElement(
+            condition: AstTestFactory.identifier3('b'),
+            thenElement: AstTestFactory.integer(1)));
+  }
+
   void test_visitIfStatement_withElse() {
     _assertSource(
         "if (c) {} else {}",
@@ -2684,12 +2635,12 @@
                 [AstTestFactory.typeName4('int')]),
             elements: [
               AstTestFactory.integer(0),
-              astFactory.collectionForElement(
+              astFactory.forElement(
                   forLoopParts: astFactory.forEachPartsWithIdentifier(
                       identifier: AstTestFactory.identifier3('e'),
                       iterable: AstTestFactory.identifier3('l')),
                   body: AstTestFactory.integer(0)),
-              astFactory.collectionIfElement(
+              astFactory.ifElement(
                   condition: AstTestFactory.identifier3('b'),
                   thenElement: AstTestFactory.integer(1)),
               astFactory.spreadElement(
@@ -2750,33 +2701,6 @@
         ]));
   }
 
-  void test_visitMapForElement() {
-    _assertSource(
-        "for (e in l) 'a' : 'b'",
-        astFactory.mapForElement(
-            forLoopParts: astFactory.forEachPartsWithIdentifier(
-                identifier: AstTestFactory.identifier3('e'),
-                iterable: AstTestFactory.identifier3('l')),
-            body: AstTestFactory.mapLiteralEntry3('a', 'b')));
-  }
-
-  void test_visitMapIfElement_else() {
-    _assertSource(
-        "if (b) 'a' : 'b' else 'c' : 'd'",
-        astFactory.mapIfElement(
-            condition: AstTestFactory.identifier3('b'),
-            thenElement: AstTestFactory.mapLiteralEntry3('a', 'b'),
-            elseElement: AstTestFactory.mapLiteralEntry3('c', 'd')));
-  }
-
-  void test_visitMapIfElement_then() {
-    _assertSource(
-        "if (b) 'a' : 'b'",
-        astFactory.mapIfElement(
-            condition: AstTestFactory.identifier3('b'),
-            thenElement: AstTestFactory.mapLiteralEntry3('a', 'b')));
-  }
-
   void test_visitMapLiteral2_complex() {
     _assertSource(
         "<String, String>{'a' : 'b', for (c in d) 'e' : 'f', if (g) 'h' : 'i', ...{'j' : 'k'}}",
@@ -2787,12 +2711,12 @@
             ]),
             entries: [
               AstTestFactory.mapLiteralEntry3('a', 'b'),
-              astFactory.mapForElement(
+              astFactory.forElement(
                   forLoopParts: astFactory.forEachPartsWithIdentifier(
                       identifier: AstTestFactory.identifier3('c'),
                       iterable: AstTestFactory.identifier3('d')),
                   body: AstTestFactory.mapLiteralEntry3('e', 'f')),
-              astFactory.mapIfElement(
+              astFactory.ifElement(
                   condition: AstTestFactory.identifier3('g'),
                   thenElement: AstTestFactory.mapLiteralEntry3('h', 'i')),
               astFactory.spreadElement(
@@ -3227,12 +3151,12 @@
                 [AstTestFactory.typeName4('int')]),
             elements: [
               AstTestFactory.integer(0),
-              astFactory.collectionForElement(
+              astFactory.forElement(
                   forLoopParts: astFactory.forEachPartsWithIdentifier(
                       identifier: AstTestFactory.identifier3('e'),
                       iterable: AstTestFactory.identifier3('l')),
                   body: AstTestFactory.integer(0)),
-              astFactory.collectionIfElement(
+              astFactory.ifElement(
                   condition: AstTestFactory.identifier3('b'),
                   thenElement: AstTestFactory.integer(1)),
               astFactory.spreadElement(
@@ -4121,33 +4045,6 @@
     _assertSource("@deprecated class C = S with M1;", declaration);
   }
 
-  void test_visitCollectionForElement() {
-    _assertSource(
-        'for (e in l) 0',
-        astFactory.collectionForElement(
-            forLoopParts: astFactory.forEachPartsWithIdentifier(
-                identifier: AstTestFactory.identifier3('e'),
-                iterable: AstTestFactory.identifier3('l')),
-            body: AstTestFactory.integer(0)));
-  }
-
-  void test_visitCollectionIfElement_else() {
-    _assertSource(
-        'if (b) 1 else 0',
-        astFactory.collectionIfElement(
-            condition: AstTestFactory.identifier3('b'),
-            thenElement: AstTestFactory.integer(1),
-            elseElement: AstTestFactory.integer(0)));
-  }
-
-  void test_visitCollectionIfElement_then() {
-    _assertSource(
-        'if (b) 1',
-        astFactory.collectionIfElement(
-            condition: AstTestFactory.identifier3('b'),
-            thenElement: AstTestFactory.integer(1)));
-  }
-
   void test_visitComment() {
     _assertSource(
         "",
@@ -4631,6 +4528,16 @@
             AstTestFactory.block()));
   }
 
+  void test_visitForElement() {
+    _assertSource(
+        'for (e in l) 0',
+        astFactory.forElement(
+            forLoopParts: astFactory.forEachPartsWithIdentifier(
+                identifier: AstTestFactory.identifier3('e'),
+                iterable: AstTestFactory.identifier3('l')),
+            body: AstTestFactory.integer(0)));
+  }
+
   void test_visitFormalParameterList_empty() {
     _assertSource("()", AstTestFactory.formalParameterList());
   }
@@ -5167,6 +5074,23 @@
                 ]))));
   }
 
+  void test_visitIfElement_else() {
+    _assertSource(
+        'if (b) 1 else 0',
+        astFactory.ifElement(
+            condition: AstTestFactory.identifier3('b'),
+            thenElement: AstTestFactory.integer(1),
+            elseElement: AstTestFactory.integer(0)));
+  }
+
+  void test_visitIfElement_then() {
+    _assertSource(
+        'if (b) 1',
+        astFactory.ifElement(
+            condition: AstTestFactory.identifier3('b'),
+            thenElement: AstTestFactory.integer(1)));
+  }
+
   void test_visitIfStatement_withElse() {
     _assertSource(
         "if (c) {} else {}",
@@ -5391,12 +5315,12 @@
                 [AstTestFactory.typeName4('int')]),
             elements: [
               AstTestFactory.integer(0),
-              astFactory.collectionForElement(
+              astFactory.forElement(
                   forLoopParts: astFactory.forEachPartsWithIdentifier(
                       identifier: AstTestFactory.identifier3('e'),
                       iterable: AstTestFactory.identifier3('l')),
                   body: AstTestFactory.integer(0)),
-              astFactory.collectionIfElement(
+              astFactory.ifElement(
                   condition: AstTestFactory.identifier3('b'),
                   thenElement: AstTestFactory.integer(1)),
               astFactory.spreadElement(
@@ -5457,33 +5381,6 @@
         ]));
   }
 
-  void test_visitMapForElement() {
-    _assertSource(
-        "for (e in l) 'a' : 'b'",
-        astFactory.mapForElement(
-            forLoopParts: astFactory.forEachPartsWithIdentifier(
-                identifier: AstTestFactory.identifier3('e'),
-                iterable: AstTestFactory.identifier3('l')),
-            body: AstTestFactory.mapLiteralEntry3('a', 'b')));
-  }
-
-  void test_visitMapIfElement_else() {
-    _assertSource(
-        "if (b) 'a' : 'b' else 'c' : 'd'",
-        astFactory.mapIfElement(
-            condition: AstTestFactory.identifier3('b'),
-            thenElement: AstTestFactory.mapLiteralEntry3('a', 'b'),
-            elseElement: AstTestFactory.mapLiteralEntry3('c', 'd')));
-  }
-
-  void test_visitMapIfElement_then() {
-    _assertSource(
-        "if (b) 'a' : 'b'",
-        astFactory.mapIfElement(
-            condition: AstTestFactory.identifier3('b'),
-            thenElement: AstTestFactory.mapLiteralEntry3('a', 'b')));
-  }
-
   void test_visitMapLiteral2_complex() {
     _assertSource(
         "<String, String>{'a' : 'b', for (c in d) 'e' : 'f', if (g) 'h' : 'i', ...{'j' : 'k'}}",
@@ -5494,12 +5391,12 @@
             ]),
             entries: [
               AstTestFactory.mapLiteralEntry3('a', 'b'),
-              astFactory.mapForElement(
+              astFactory.forElement(
                   forLoopParts: astFactory.forEachPartsWithIdentifier(
                       identifier: AstTestFactory.identifier3('c'),
                       iterable: AstTestFactory.identifier3('d')),
                   body: AstTestFactory.mapLiteralEntry3('e', 'f')),
-              astFactory.mapIfElement(
+              astFactory.ifElement(
                   condition: AstTestFactory.identifier3('g'),
                   thenElement: AstTestFactory.mapLiteralEntry3('h', 'i')),
               astFactory.spreadElement(
@@ -5925,12 +5822,12 @@
                 [AstTestFactory.typeName4('int')]),
             elements: [
               AstTestFactory.integer(0),
-              astFactory.collectionForElement(
+              astFactory.forElement(
                   forLoopParts: astFactory.forEachPartsWithIdentifier(
                       identifier: AstTestFactory.identifier3('e'),
                       iterable: AstTestFactory.identifier3('l')),
                   body: AstTestFactory.integer(0)),
-              astFactory.collectionIfElement(
+              astFactory.ifElement(
                   condition: AstTestFactory.identifier3('b'),
                   thenElement: AstTestFactory.integer(1)),
               astFactory.spreadElement(
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/syntactic_scope.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/syntactic_scope.dart
index df8bd22..71cf0f0 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/syntactic_scope.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/syntactic_scope.dart
@@ -133,15 +133,6 @@
   }
 
   @override
-  void visitCollectionForElement(CollectionForElement node) {
-    if (!_isCoveredBy(node)) return;
-
-    _addForLoopParts(node.forLoopParts, node.body);
-
-    super.visitCollectionForElement(node);
-  }
-
-  @override
   void visitConstructorDeclaration(ConstructorDeclaration node) {
     if (!_isCoveredBy(node)) return;
 
@@ -163,6 +154,15 @@
   }
 
   @override
+  void visitForElement(ForElement node) {
+    if (!_isCoveredBy(node)) return;
+
+    _addForLoopParts(node.forLoopParts, node.body);
+
+    super.visitForElement(node);
+  }
+
+  @override
   void visitForStatement(ForStatement node) {
     if (!_isCoveredBy(node)) return;
 
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index ec56994..54e0f0f 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -6422,10 +6422,10 @@
   visitWithClause(node) => _unreachable(node);
 
   @override
-  visitCollectionForElement(CollectionForElement node) => _unreachable(node);
+  visitForElement(ForElement node) => _unreachable(node);
 
   @override
-  visitCollectionIfElement(CollectionIfElement node) => _unreachable(node);
+  visitIfElement(IfElement node) => _unreachable(node);
 
   @override
   visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) =>
@@ -6442,12 +6442,6 @@
   visitListLiteral2(ListLiteral2 node) => _unreachable(node);
 
   @override
-  visitMapForElement(MapForElement node) => _unreachable(node);
-
-  @override
-  visitMapIfElement(MapIfElement node) => _unreachable(node);
-
-  @override
   visitMapLiteral2(MapLiteral2 node) => _unreachable(node);
 
   @override