diff --git a/pkg/analyzer-experimental/lib/src/generated/ast.dart b/pkg/analyzer-experimental/lib/src/generated/ast.dart
index 4e808bf..c7e03c7 100644
--- a/pkg/analyzer-experimental/lib/src/generated/ast.dart
+++ b/pkg/analyzer-experimental/lib/src/generated/ast.dart
@@ -8,7 +8,8 @@
 import 'java_engine.dart';
 import 'error.dart';
 import 'scanner.dart';
-import 'package:analyzer-experimental/src/generated/utilities_dart.dart';
+import 'engine.dart' show AnalysisEngine;
+import 'utilities_dart.dart';
 import 'element.dart' hide Annotation;
 
 /**
@@ -33,6 +34,18 @@
    */
   accept(ASTVisitor visitor);
   /**
+   * @return the {@link ASTNode} of given {@link Class} which is {@link ASTNode} itself, or one of
+   * its parents.
+   */
+  ASTNode getAncestor(Type enclosingClass) {
+    ASTNode node = this;
+    while (node != null && !isInstanceOf(node, enclosingClass)) {
+      node = node.parent;
+    }
+    ;
+    return (node as ASTNode);
+  }
+  /**
    * Return the first token included in this node's source range.
    * @return the first token included in this node's source range
    */
@@ -56,11 +69,11 @@
    */
   int get length {
     Token beginToken2 = beginToken;
-    Token endToken3 = endToken;
-    if (beginToken2 == null || endToken3 == null) {
+    Token endToken2 = endToken;
+    if (beginToken2 == null || endToken2 == null) {
       return -1;
     }
-    return endToken3.offset + endToken3.length - beginToken2.offset;
+    return endToken2.offset + endToken2.length - beginToken2.offset;
   }
   /**
    * Return the offset from the beginning of the file to the first character in the node's source
@@ -90,10 +103,10 @@
    */
   ASTNode get root {
     ASTNode root = this;
-    ASTNode parent3 = parent;
-    while (parent3 != null) {
-      root = parent3;
-      parent3 = root.parent;
+    ASTNode parent2 = parent;
+    while (parent2 != null) {
+      root = parent2;
+      parent2 = root.parent;
     }
     return root;
   }
@@ -129,7 +142,7 @@
   ASTNode becomeParentOf(ASTNode child) {
     if (child != null) {
       ASTNode node = child;
-      node.parent2 = this;
+      node.parent = this;
     }
     return child;
   }
@@ -147,9 +160,11 @@
    * Set the parent of this node to the given node.
    * @param newParent the node that is to be made the parent of this node
    */
-  void set parent2(ASTNode newParent) {
+  void set parent(ASTNode newParent) {
     _parent = newParent;
   }
+  static int _hashCodeGenerator = 0;
+  final int hashCode = ++_hashCodeGenerator;
 }
 /**
  * The interface {@code ASTVisitor} defines the behavior of objects that can be used to visit an AST
@@ -274,10 +289,15 @@
    * Initialize a newly created list of adjacent strings.
    * @param strings the strings that are implicitly concatenated
    */
-  AdjacentStrings(List<StringLiteral> strings) {
+  AdjacentStrings.full(List<StringLiteral> strings) {
     this._strings = new NodeList<StringLiteral>(this);
     this._strings.addAll(strings);
   }
+  /**
+   * Initialize a newly created list of adjacent strings.
+   * @param strings the strings that are implicitly concatenated
+   */
+  AdjacentStrings({List<StringLiteral> strings}) : this.full(strings);
   accept(ASTVisitor visitor) => visitor.visitAdjacentStrings(this);
   Token get beginToken => _strings.beginToken;
   Token get endToken => _strings.endToken;
@@ -309,11 +329,17 @@
    * @param comment the documentation comment associated with this node
    * @param metadata the annotations associated with this node
    */
-  AnnotatedNode(Comment comment, List<Annotation> metadata) {
+  AnnotatedNode.full(Comment comment, List<Annotation> metadata) {
     this._metadata = new NodeList<Annotation>(this);
     this._comment = becomeParentOf(comment);
     this._metadata.addAll(metadata);
   }
+  /**
+   * Initialize a newly created node.
+   * @param comment the documentation comment associated with this node
+   * @param metadata the annotations associated with this node
+   */
+  AnnotatedNode({Comment comment, List<Annotation> metadata}) : this.full(comment, metadata);
   Token get beginToken {
     if (_comment == null) {
       if (_metadata.isEmpty) {
@@ -346,8 +372,8 @@
    * Set the documentation comment associated with this node to the given comment
    * @param comment the documentation comment to be associated with this node
    */
-  void set documentationComment(Comment comment) {
-    this._comment = becomeParentOf(comment);
+  void set documentationComment(Comment comment2) {
+    this._comment = becomeParentOf(comment2);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     if (commentIsBeforeAnnotations()) {
@@ -437,13 +463,26 @@
    * @param arguments the arguments to the constructor being invoked, or {@code null} if this
    * annotation is not the invocation of a constructor
    */
-  Annotation(Token atSign, Identifier name, Token period, SimpleIdentifier constructorName, ArgumentList arguments) {
+  Annotation.full(Token atSign, Identifier name, Token period, SimpleIdentifier constructorName, ArgumentList arguments) {
     this._atSign = atSign;
     this._name = becomeParentOf(name);
     this._period = period;
     this._constructorName = becomeParentOf(constructorName);
     this._arguments = becomeParentOf(arguments);
   }
+  /**
+   * Initialize a newly created annotation.
+   * @param atSign the at sign that introduced the annotation
+   * @param name the name of the class defining the constructor that is being invoked or the name of
+   * the field that is being referenced
+   * @param period the period before the constructor name, or {@code null} if this annotation is not
+   * the invocation of a named constructor
+   * @param constructorName the name of the constructor being invoked, or {@code null} if this
+   * annotation is not the invocation of a named constructor
+   * @param arguments the arguments to the constructor being invoked, or {@code null} if this
+   * annotation is not the invocation of a constructor
+   */
+  Annotation({Token atSign, Identifier name, Token period, SimpleIdentifier constructorName, ArgumentList arguments}) : this.full(atSign, name, period, constructorName, arguments);
   accept(ASTVisitor visitor) => visitor.visitAnnotation(this);
   /**
    * Return the arguments to the constructor being invoked, or {@code null} if this annotation is
@@ -487,37 +526,37 @@
    * Set the arguments to the constructor being invoked to the given arguments.
    * @param arguments the arguments to the constructor being invoked
    */
-  void set arguments2(ArgumentList arguments) {
-    this._arguments = becomeParentOf(arguments);
+  void set arguments(ArgumentList arguments2) {
+    this._arguments = becomeParentOf(arguments2);
   }
   /**
    * Set the at sign that introduced the annotation to the given token.
    * @param atSign the at sign that introduced the annotation
    */
-  void set atSign2(Token atSign) {
-    this._atSign = atSign;
+  void set atSign(Token atSign2) {
+    this._atSign = atSign2;
   }
   /**
    * Set the name of the constructor being invoked to the given name.
    * @param constructorName the name of the constructor being invoked
    */
-  void set constructorName2(SimpleIdentifier constructorName) {
-    this._constructorName = becomeParentOf(constructorName);
+  void set constructorName(SimpleIdentifier constructorName2) {
+    this._constructorName = becomeParentOf(constructorName2);
   }
   /**
    * Set the name of the class defining the constructor that is being invoked or the name of the
    * field that is being referenced to the given name.
    * @param name the name of the constructor being invoked or the name of the field being referenced
    */
-  void set name2(Identifier name) {
-    this._name = becomeParentOf(name);
+  void set name(Identifier name2) {
+    this._name = becomeParentOf(name2);
   }
   /**
    * Set the period before the constructor name to the given token.
    * @param period the period before the constructor name
    */
-  void set period2(Token period) {
-    this._period = period;
+  void set period(Token period2) {
+    this._period = period2;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_name, visitor);
@@ -545,10 +584,16 @@
    * @param question the token representing the question mark
    * @param identifier the identifier representing the argument being tested
    */
-  ArgumentDefinitionTest(Token question, SimpleIdentifier identifier) {
+  ArgumentDefinitionTest.full(Token question, SimpleIdentifier identifier) {
     this._question = question;
     this._identifier = becomeParentOf(identifier);
   }
+  /**
+   * Initialize a newly created argument definition test.
+   * @param question the token representing the question mark
+   * @param identifier the identifier representing the argument being tested
+   */
+  ArgumentDefinitionTest({Token question, SimpleIdentifier identifier}) : this.full(question, identifier);
   accept(ASTVisitor visitor) => visitor.visitArgumentDefinitionTest(this);
   Token get beginToken => _question;
   Token get endToken => _identifier.endToken;
@@ -566,15 +611,15 @@
    * Set the identifier representing the argument being tested to the given identifier.
    * @param identifier the identifier representing the argument being tested
    */
-  void set identifier2(SimpleIdentifier identifier) {
-    this._identifier = becomeParentOf(identifier);
+  void set identifier(SimpleIdentifier identifier5) {
+    this._identifier = becomeParentOf(identifier5);
   }
   /**
    * Set the token representing the question mark to the given token.
    * @param question the token representing the question mark
    */
-  void set question2(Token question) {
-    this._question = question;
+  void set question(Token question2) {
+    this._question = question2;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_identifier, visitor);
@@ -609,12 +654,19 @@
    * @param arguments the expressions producing the values of the arguments
    * @param rightParenthesis the right parenthesis
    */
-  ArgumentList(Token leftParenthesis, List<Expression> arguments, Token rightParenthesis) {
+  ArgumentList.full(Token leftParenthesis, List<Expression> arguments, Token rightParenthesis) {
     this._arguments = new NodeList<Expression>(this);
     this._leftParenthesis = leftParenthesis;
     this._arguments.addAll(arguments);
     this._rightParenthesis = rightParenthesis;
   }
+  /**
+   * Initialize a newly created list of arguments.
+   * @param leftParenthesis the left parenthesis
+   * @param arguments the expressions producing the values of the arguments
+   * @param rightParenthesis the right parenthesis
+   */
+  ArgumentList({Token leftParenthesis, List<Expression> arguments, Token rightParenthesis}) : this.full(leftParenthesis, arguments, rightParenthesis);
   accept(ASTVisitor visitor) => visitor.visitArgumentList(this);
   /**
    * Return the expressions producing the values of the arguments. Although the language requires
@@ -639,14 +691,14 @@
    * Set the left parenthesis to the given token.
    * @param parenthesis the left parenthesis
    */
-  void set leftParenthesis2(Token parenthesis) {
+  void set leftParenthesis(Token parenthesis) {
     _leftParenthesis = parenthesis;
   }
   /**
    * Set the right parenthesis to the given token.
    * @param parenthesis the right parenthesis
    */
-  void set rightParenthesis2(Token parenthesis) {
+  void set rightParenthesis(Token parenthesis) {
     _rightParenthesis = parenthesis;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -677,11 +729,18 @@
    * @param isOperator the is operator
    * @param type the name of the type being cast to
    */
-  AsExpression(Expression expression, Token isOperator, TypeName type) {
+  AsExpression.full(Expression expression, Token isOperator, TypeName type) {
     this._expression = becomeParentOf(expression);
     this._asOperator = isOperator;
     this._type = becomeParentOf(type);
   }
+  /**
+   * Initialize a newly created as expression.
+   * @param expression the expression used to compute the value being cast
+   * @param isOperator the is operator
+   * @param type the name of the type being cast to
+   */
+  AsExpression({Expression expression, Token isOperator, TypeName type}) : this.full(expression, isOperator, type);
   accept(ASTVisitor visitor) => visitor.visitAsExpression(this);
   /**
    * Return the is operator being applied.
@@ -704,21 +763,21 @@
    * Set the is operator being applied to the given operator.
    * @param asOperator the is operator being applied
    */
-  void set asOperator2(Token asOperator) {
-    this._asOperator = asOperator;
+  void set asOperator(Token asOperator2) {
+    this._asOperator = asOperator2;
   }
   /**
    * Set the expression used to compute the value being cast to the given expression.
    * @param expression the expression used to compute the value being cast
    */
-  void set expression2(Expression expression) {
-    this._expression = becomeParentOf(expression);
+  void set expression(Expression expression2) {
+    this._expression = becomeParentOf(expression2);
   }
   /**
    * Set the name of the type being cast to to the given name.
    * @param name the name of the type being cast to
    */
-  void set type2(TypeName name) {
+  void set type(TypeName name) {
     this._type = becomeParentOf(name);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -762,13 +821,22 @@
    * @param rightParenthesis the right parenthesis
    * @param semicolon the semicolon terminating the statement
    */
-  AssertStatement(Token keyword, Token leftParenthesis, Expression condition, Token rightParenthesis, Token semicolon) {
+  AssertStatement.full(Token keyword, Token leftParenthesis, Expression condition, Token rightParenthesis, Token semicolon) {
     this._keyword = keyword;
     this._leftParenthesis = leftParenthesis;
     this._condition = becomeParentOf(condition);
     this._rightParenthesis = rightParenthesis;
     this._semicolon = semicolon;
   }
+  /**
+   * Initialize a newly created assert statement.
+   * @param keyword the token representing the 'assert' keyword
+   * @param leftParenthesis the left parenthesis
+   * @param condition the condition that is being asserted to be {@code true}
+   * @param rightParenthesis the right parenthesis
+   * @param semicolon the semicolon terminating the statement
+   */
+  AssertStatement({Token keyword, Token leftParenthesis, Expression condition, Token rightParenthesis, Token semicolon}) : this.full(keyword, leftParenthesis, condition, rightParenthesis, semicolon);
   accept(ASTVisitor visitor) => visitor.visitAssertStatement(this);
   Token get beginToken => _keyword;
   /**
@@ -801,36 +869,36 @@
    * Set the condition that is being asserted to be {@code true} to the given expression.
    * @param the condition that is being asserted to be {@code true}
    */
-  void set condition2(Expression condition) {
-    this._condition = becomeParentOf(condition);
+  void set condition(Expression condition2) {
+    this._condition = becomeParentOf(condition2);
   }
   /**
    * Set the token representing the 'assert' keyword to the given token.
    * @param keyword the token representing the 'assert' keyword
    */
-  void set keyword3(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword3) {
+    this._keyword = keyword3;
   }
   /**
    * Set the left parenthesis to the given token.
    * @param the left parenthesis
    */
-  void set leftParenthesis3(Token leftParenthesis) {
-    this._leftParenthesis = leftParenthesis;
+  void set leftParenthesis(Token leftParenthesis2) {
+    this._leftParenthesis = leftParenthesis2;
   }
   /**
    * Set the right parenthesis to the given token.
    * @param rightParenthesis the right parenthesis
    */
-  void set rightParenthesis3(Token rightParenthesis) {
-    this._rightParenthesis = rightParenthesis;
+  void set rightParenthesis(Token rightParenthesis2) {
+    this._rightParenthesis = rightParenthesis2;
   }
   /**
    * Set the semicolon terminating the statement to the given token.
    * @param semicolon the semicolon terminating the statement
    */
-  void set semicolon2(Token semicolon) {
-    this._semicolon = semicolon;
+  void set semicolon(Token semicolon2) {
+    this._semicolon = semicolon2;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_condition, visitor);
@@ -865,11 +933,18 @@
    * @param operator the assignment operator being applied
    * @param rightHandSide the expression used to compute the right hand side
    */
-  AssignmentExpression(Expression leftHandSide, Token operator, Expression rightHandSide) {
+  AssignmentExpression.full(Expression leftHandSide, Token operator, Expression rightHandSide) {
     this._leftHandSide = becomeParentOf(leftHandSide);
     this._operator = operator;
     this._rightHandSide = becomeParentOf(rightHandSide);
   }
+  /**
+   * Initialize a newly created assignment expression.
+   * @param leftHandSide the expression used to compute the left hand side
+   * @param operator the assignment operator being applied
+   * @param rightHandSide the expression used to compute the right hand side
+   */
+  AssignmentExpression({Expression leftHandSide, Token operator, Expression rightHandSide}) : this.full(leftHandSide, operator, rightHandSide);
   accept(ASTVisitor visitor) => visitor.visitAssignmentExpression(this);
   Token get beginToken => _leftHandSide.beginToken;
   /**
@@ -900,28 +975,28 @@
    * Set the element associated with the operator to the given element.
    * @param element the element associated with the operator
    */
-  void set element2(MethodElement element) {
-    this._element = element;
+  void set element(MethodElement element3) {
+    this._element = element3;
   }
   /**
    * Return the expression used to compute the left hand side.
    * @param expression the expression used to compute the left hand side
    */
-  void set leftHandSide2(Expression expression) {
+  void set leftHandSide(Expression expression) {
     _leftHandSide = becomeParentOf(expression);
   }
   /**
    * Set the assignment operator being applied to the given operator.
    * @param operator the assignment operator being applied
    */
-  void set operator2(Token operator) {
-    this._operator = operator;
+  void set operator(Token operator2) {
+    this._operator = operator2;
   }
   /**
    * Set the expression used to compute the left hand side to the given expression.
    * @param expression the expression used to compute the left hand side
    */
-  void set rightHandSide2(Expression expression) {
+  void set rightHandSide(Expression expression) {
     _rightHandSide = becomeParentOf(expression);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -958,11 +1033,18 @@
    * @param operator the binary operator being applied
    * @param rightOperand the expression used to compute the right operand
    */
-  BinaryExpression(Expression leftOperand, Token operator, Expression rightOperand) {
+  BinaryExpression.full(Expression leftOperand, Token operator, Expression rightOperand) {
     this._leftOperand = becomeParentOf(leftOperand);
     this._operator = operator;
     this._rightOperand = becomeParentOf(rightOperand);
   }
+  /**
+   * Initialize a newly created binary expression.
+   * @param leftOperand the expression used to compute the left operand
+   * @param operator the binary operator being applied
+   * @param rightOperand the expression used to compute the right operand
+   */
+  BinaryExpression({Expression leftOperand, Token operator, Expression rightOperand}) : this.full(leftOperand, operator, rightOperand);
   accept(ASTVisitor visitor) => visitor.visitBinaryExpression(this);
   Token get beginToken => _leftOperand.beginToken;
   /**
@@ -993,28 +1075,28 @@
    * Set the element associated with the operator to the given element.
    * @param element the element associated with the operator
    */
-  void set element3(MethodElement element) {
-    this._element = element;
+  void set element(MethodElement element4) {
+    this._element = element4;
   }
   /**
    * Set the expression used to compute the left operand to the given expression.
    * @param expression the expression used to compute the left operand
    */
-  void set leftOperand2(Expression expression) {
+  void set leftOperand(Expression expression) {
     _leftOperand = becomeParentOf(expression);
   }
   /**
    * Set the binary operator being applied to the given operator.
    * @return the binary operator being applied
    */
-  void set operator3(Token operator) {
-    this._operator = operator;
+  void set operator(Token operator3) {
+    this._operator = operator3;
   }
   /**
    * Set the expression used to compute the right operand to the given expression.
    * @param expression the expression used to compute the right operand
    */
-  void set rightOperand2(Expression expression) {
+  void set rightOperand(Expression expression) {
     _rightOperand = becomeParentOf(expression);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -1048,12 +1130,19 @@
    * @param statements the statements contained in the block
    * @param rightBracket the right curly bracket
    */
-  Block(Token leftBracket, List<Statement> statements, Token rightBracket) {
+  Block.full(Token leftBracket, List<Statement> statements, Token rightBracket) {
     this._statements = new NodeList<Statement>(this);
     this._leftBracket = leftBracket;
     this._statements.addAll(statements);
     this._rightBracket = rightBracket;
   }
+  /**
+   * Initialize a newly created block of code.
+   * @param leftBracket the left curly bracket
+   * @param statements the statements contained in the block
+   * @param rightBracket the right curly bracket
+   */
+  Block({Token leftBracket, List<Statement> statements, Token rightBracket}) : this.full(leftBracket, statements, rightBracket);
   accept(ASTVisitor visitor) => visitor.visitBlock(this);
   Token get beginToken => _leftBracket;
   Token get endToken => _rightBracket;
@@ -1076,15 +1165,15 @@
    * Set the left curly bracket to the given token.
    * @param leftBracket the left curly bracket
    */
-  void set leftBracket2(Token leftBracket) {
-    this._leftBracket = leftBracket;
+  void set leftBracket(Token leftBracket2) {
+    this._leftBracket = leftBracket2;
   }
   /**
    * Set the right curly bracket to the given token.
    * @param rightBracket the right curly bracket
    */
-  void set rightBracket2(Token rightBracket) {
-    this._rightBracket = rightBracket;
+  void set rightBracket(Token rightBracket2) {
+    this._rightBracket = rightBracket2;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     _statements.accept(visitor);
@@ -1105,9 +1194,14 @@
    * Initialize a newly created function body consisting of a block of statements.
    * @param block the block representing the body of the function
    */
-  BlockFunctionBody(Block block) {
+  BlockFunctionBody.full(Block block) {
     this._block = becomeParentOf(block);
   }
+  /**
+   * Initialize a newly created function body consisting of a block of statements.
+   * @param block the block representing the body of the function
+   */
+  BlockFunctionBody({Block block}) : this.full(block);
   accept(ASTVisitor visitor) => visitor.visitBlockFunctionBody(this);
   Token get beginToken => _block.beginToken;
   /**
@@ -1120,8 +1214,8 @@
    * Set the block representing the body of the function to the given block.
    * @param block the block representing the body of the function
    */
-  void set block2(Block block) {
-    this._block = becomeParentOf(block);
+  void set block(Block block2) {
+    this._block = becomeParentOf(block2);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_block, visitor);
@@ -1148,10 +1242,16 @@
    * @param literal the token representing the literal
    * @param value the value of the literal
    */
-  BooleanLiteral(Token literal, bool value) {
+  BooleanLiteral.full(Token literal, bool value) {
     this._literal = literal;
     this._value = value;
   }
+  /**
+   * Initialize a newly created boolean literal.
+   * @param literal the token representing the literal
+   * @param value the value of the literal
+   */
+  BooleanLiteral({Token literal, bool value}) : this.full(literal, value);
   accept(ASTVisitor visitor) => visitor.visitBooleanLiteral(this);
   Token get beginToken => _literal;
   Token get endToken => _literal;
@@ -1170,15 +1270,15 @@
    * Set the token representing the literal to the given token.
    * @param literal the token representing the literal
    */
-  void set literal2(Token literal) {
-    this._literal = literal;
+  void set literal(Token literal2) {
+    this._literal = literal2;
   }
   /**
    * Set the value of the literal to the given value.
    * @param value the value of the literal
    */
-  void set value4(bool value) {
-    this._value = value;
+  void set value(bool value4) {
+    this._value = value4;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
   }
@@ -1209,11 +1309,18 @@
    * @param label the label associated with the statement
    * @param semicolon the semicolon terminating the statement
    */
-  BreakStatement(Token keyword, SimpleIdentifier label, Token semicolon) {
+  BreakStatement.full(Token keyword, SimpleIdentifier label, Token semicolon) {
     this._keyword = keyword;
     this._label = becomeParentOf(label);
     this._semicolon = semicolon;
   }
+  /**
+   * Initialize a newly created break statement.
+   * @param keyword the token representing the 'break' keyword
+   * @param label the label associated with the statement
+   * @param semicolon the semicolon terminating the statement
+   */
+  BreakStatement({Token keyword, SimpleIdentifier label, Token semicolon}) : this.full(keyword, label, semicolon);
   accept(ASTVisitor visitor) => visitor.visitBreakStatement(this);
   Token get beginToken => _keyword;
   Token get endToken => _semicolon;
@@ -1236,22 +1343,22 @@
    * Set the token representing the 'break' keyword to the given token.
    * @param keyword the token representing the 'break' keyword
    */
-  void set keyword4(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword4) {
+    this._keyword = keyword4;
   }
   /**
    * Set the label associated with the statement to the given identifier.
    * @param identifier the label associated with the statement
    */
-  void set label2(SimpleIdentifier identifier) {
+  void set label(SimpleIdentifier identifier) {
     _label = becomeParentOf(identifier);
   }
   /**
    * Set the semicolon terminating the statement to the given token.
    * @param semicolon the semicolon terminating the statement
    */
-  void set semicolon3(Token semicolon) {
-    this._semicolon = semicolon;
+  void set semicolon(Token semicolon3) {
+    this._semicolon = semicolon3;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_label, visitor);
@@ -1284,11 +1391,17 @@
    * @param target the target of the cascade sections
    * @param cascadeSections the cascade sections sharing the common target
    */
-  CascadeExpression(Expression target, List<Expression> cascadeSections) {
+  CascadeExpression.full(Expression target, List<Expression> cascadeSections) {
     this._cascadeSections = new NodeList<Expression>(this);
     this._target = becomeParentOf(target);
     this._cascadeSections.addAll(cascadeSections);
   }
+  /**
+   * Initialize a newly created cascade expression.
+   * @param target the target of the cascade sections
+   * @param cascadeSections the cascade sections sharing the common target
+   */
+  CascadeExpression({Expression target, List<Expression> cascadeSections}) : this.full(target, cascadeSections);
   accept(ASTVisitor visitor) => visitor.visitCascadeExpression(this);
   Token get beginToken => _target.beginToken;
   /**
@@ -1306,8 +1419,8 @@
    * Set the target of the cascade sections to the given expression.
    * @param target the target of the cascade sections
    */
-  void set target2(Expression target) {
-    this._target = becomeParentOf(target);
+  void set target(Expression target2) {
+    this._target = becomeParentOf(target2);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_target, visitor);
@@ -1372,7 +1485,7 @@
    * @param rightParenthesis the right parenthesis
    * @param body the body of the catch block
    */
-  CatchClause(Token onKeyword, TypeName exceptionType, Token catchKeyword, Token leftParenthesis, SimpleIdentifier exceptionParameter, Token comma, SimpleIdentifier stackTraceParameter, Token rightParenthesis, Block body) {
+  CatchClause.full(Token onKeyword, TypeName exceptionType, Token catchKeyword, Token leftParenthesis, SimpleIdentifier exceptionParameter, Token comma, SimpleIdentifier stackTraceParameter, Token rightParenthesis, Block body) {
     this._onKeyword = onKeyword;
     this._exceptionType = becomeParentOf(exceptionType);
     this._catchKeyword = catchKeyword;
@@ -1383,6 +1496,19 @@
     this._rightParenthesis = rightParenthesis;
     this._body = becomeParentOf(body);
   }
+  /**
+   * Initialize a newly created catch clause.
+   * @param onKeyword the token representing the 'on' keyword
+   * @param exceptionType the type of exceptions caught by this catch clause
+   * @param leftParenthesis the left parenthesis
+   * @param exceptionParameter the parameter whose value will be the exception that was thrown
+   * @param comma the comma separating the exception parameter from the stack trace parameter
+   * @param stackTraceParameter the parameter whose value will be the stack trace associated with
+   * the exception
+   * @param rightParenthesis the right parenthesis
+   * @param body the body of the catch block
+   */
+  CatchClause({Token onKeyword, TypeName exceptionType, Token catchKeyword, Token leftParenthesis, SimpleIdentifier exceptionParameter, Token comma, SimpleIdentifier stackTraceParameter, Token rightParenthesis, Block body}) : this.full(onKeyword, exceptionType, catchKeyword, leftParenthesis, exceptionParameter, comma, stackTraceParameter, rightParenthesis, body);
   accept(ASTVisitor visitor) => visitor.visitCatchClause(this);
   Token get beginToken {
     if (_onKeyword != null) {
@@ -1442,56 +1568,56 @@
    * Set the body of the catch block to the given block.
    * @param block the body of the catch block
    */
-  void set body2(Block block) {
+  void set body(Block block) {
     _body = becomeParentOf(block);
   }
   /**
    * Set the token representing the 'catch' keyword to the given token.
    * @param catchKeyword the token representing the 'catch' keyword
    */
-  void set catchKeyword2(Token catchKeyword) {
-    this._catchKeyword = catchKeyword;
+  void set catchKeyword(Token catchKeyword2) {
+    this._catchKeyword = catchKeyword2;
   }
   /**
    * Set the comma to the given token.
    * @param comma the comma
    */
-  void set comma2(Token comma) {
-    this._comma = comma;
+  void set comma(Token comma2) {
+    this._comma = comma2;
   }
   /**
    * Set the parameter whose value will be the exception that was thrown to the given parameter.
    * @param parameter the parameter whose value will be the exception that was thrown
    */
-  void set exceptionParameter2(SimpleIdentifier parameter) {
+  void set exceptionParameter(SimpleIdentifier parameter) {
     _exceptionParameter = becomeParentOf(parameter);
   }
   /**
    * Set the type of exceptions caught by this catch clause to the given type.
    * @param exceptionType the type of exceptions caught by this catch clause
    */
-  void set exceptionType2(TypeName exceptionType) {
-    this._exceptionType = exceptionType;
+  void set exceptionType(TypeName exceptionType2) {
+    this._exceptionType = exceptionType2;
   }
   /**
    * Set the left parenthesis to the given token.
    * @param parenthesis the left parenthesis
    */
-  void set leftParenthesis4(Token parenthesis) {
+  void set leftParenthesis(Token parenthesis) {
     _leftParenthesis = parenthesis;
   }
   /**
    * Set the token representing the 'on' keyword to the given keyword.
    * @param onKeyword the token representing the 'on' keyword
    */
-  void set onKeyword2(Token onKeyword) {
-    this._onKeyword = onKeyword;
+  void set onKeyword(Token onKeyword2) {
+    this._onKeyword = onKeyword2;
   }
   /**
    * Set the right parenthesis to the given token.
    * @param parenthesis the right parenthesis
    */
-  void set rightParenthesis4(Token parenthesis) {
+  void set rightParenthesis(Token parenthesis) {
     _rightParenthesis = parenthesis;
   }
   /**
@@ -1500,7 +1626,7 @@
    * @param parameter the parameter whose value will be the stack trace associated with the
    * exception
    */
-  void set stackTraceParameter2(SimpleIdentifier parameter) {
+  void set stackTraceParameter(SimpleIdentifier parameter) {
     _stackTraceParameter = becomeParentOf(parameter);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -1577,7 +1703,7 @@
    * @param members the members defined by the class
    * @param rightBracket the right curly bracket
    */
-  ClassDeclaration(Comment comment, List<Annotation> metadata, Token abstractKeyword, Token classKeyword, SimpleIdentifier name, TypeParameterList typeParameters, ExtendsClause extendsClause, WithClause withClause, ImplementsClause implementsClause, Token leftBracket, List<ClassMember> members, Token rightBracket) : super(comment, metadata) {
+  ClassDeclaration.full(Comment comment, List<Annotation> metadata, Token abstractKeyword, Token classKeyword, SimpleIdentifier name, TypeParameterList typeParameters, ExtendsClause extendsClause, WithClause withClause, ImplementsClause implementsClause, Token leftBracket, List<ClassMember> members, Token rightBracket) : super.full(comment, metadata) {
     this._members = new NodeList<ClassMember>(this);
     this._abstractKeyword = abstractKeyword;
     this._classKeyword = classKeyword;
@@ -1590,6 +1716,22 @@
     this._members.addAll(members);
     this._rightBracket = rightBracket;
   }
+  /**
+   * Initialize a newly created class declaration.
+   * @param comment the documentation comment associated with this class
+   * @param metadata the annotations associated with this class
+   * @param abstractKeyword the 'abstract' keyword, or {@code null} if the keyword was absent
+   * @param classKeyword the token representing the 'class' keyword
+   * @param name the name of the class being declared
+   * @param typeParameters the type parameters for the class
+   * @param extendsClause the extends clause for the class
+   * @param withClause the with clause for the class
+   * @param implementsClause the implements clause for the class
+   * @param leftBracket the left curly bracket
+   * @param members the members defined by the class
+   * @param rightBracket the right curly bracket
+   */
+  ClassDeclaration({Comment comment, List<Annotation> metadata, Token abstractKeyword, Token classKeyword, SimpleIdentifier name, TypeParameterList typeParameters, ExtendsClause extendsClause, WithClause withClause, ImplementsClause implementsClause, Token leftBracket, List<ClassMember> members, Token rightBracket}) : this.full(comment, metadata, abstractKeyword, classKeyword, name, typeParameters, extendsClause, withClause, implementsClause, leftBracket, members, rightBracket);
   accept(ASTVisitor visitor) => visitor.visitClassDeclaration(this);
   /**
    * Return the 'abstract' keyword, or {@code null} if the keyword was absent.
@@ -1605,7 +1747,7 @@
    * @return the {@link ClassElement} associated with this identifier, or {@code null} if the AST
    * structure has not been resolved or if this identifier could not be resolved.
    */
-  ClassElement get element => _name != null ? _name.element as ClassElement : null;
+  ClassElement get element => _name != null ? (_name.element as ClassElement) : null;
   Token get endToken => _rightBracket;
   /**
    * Return the extends clause for this class, or {@code null} if the class does not extend any
@@ -1654,64 +1796,64 @@
    * Set the 'abstract' keyword to the given keyword.
    * @param abstractKeyword the 'abstract' keyword
    */
-  void set abstractKeyword2(Token abstractKeyword) {
-    this._abstractKeyword = abstractKeyword;
+  void set abstractKeyword(Token abstractKeyword2) {
+    this._abstractKeyword = abstractKeyword2;
   }
   /**
    * Set the token representing the 'class' keyword to the given token.
    * @param classKeyword the token representing the 'class' keyword
    */
-  void set classKeyword2(Token classKeyword) {
-    this._classKeyword = classKeyword;
+  void set classKeyword(Token classKeyword2) {
+    this._classKeyword = classKeyword2;
   }
   /**
    * Set the extends clause for this class to the given clause.
    * @param extendsClause the extends clause for this class
    */
-  void set extendsClause2(ExtendsClause extendsClause) {
-    this._extendsClause = becomeParentOf(extendsClause);
+  void set extendsClause(ExtendsClause extendsClause3) {
+    this._extendsClause = becomeParentOf(extendsClause3);
   }
   /**
    * Set the implements clause for the class to the given clause.
    * @param implementsClause the implements clause for the class
    */
-  void set implementsClause2(ImplementsClause implementsClause) {
-    this._implementsClause = becomeParentOf(implementsClause);
+  void set implementsClause(ImplementsClause implementsClause4) {
+    this._implementsClause = becomeParentOf(implementsClause4);
   }
   /**
    * Set the left curly bracket to the given token.
    * @param leftBracket the left curly bracket
    */
-  void set leftBracket3(Token leftBracket) {
-    this._leftBracket = leftBracket;
+  void set leftBracket(Token leftBracket3) {
+    this._leftBracket = leftBracket3;
   }
   /**
    * Set the name of the class being declared to the given identifier.
    * @param identifier the name of the class being declared
    */
-  void set name3(SimpleIdentifier identifier) {
+  void set name(SimpleIdentifier identifier) {
     _name = becomeParentOf(identifier);
   }
   /**
    * Set the right curly bracket to the given token.
    * @param rightBracket the right curly bracket
    */
-  void set rightBracket3(Token rightBracket) {
-    this._rightBracket = rightBracket;
+  void set rightBracket(Token rightBracket3) {
+    this._rightBracket = rightBracket3;
   }
   /**
    * Set the type parameters for the class to the given list of type parameters.
    * @param typeParameters the type parameters for the class
    */
-  void set typeParameters2(TypeParameterList typeParameters) {
-    this._typeParameters = typeParameters;
+  void set typeParameters(TypeParameterList typeParameters2) {
+    this._typeParameters = typeParameters2;
   }
   /**
    * Set the with clause for the class to the given clause.
    * @param withClause the with clause for the class
    */
-  void set withClause2(WithClause withClause) {
-    this._withClause = becomeParentOf(withClause);
+  void set withClause(WithClause withClause4) {
+    this._withClause = becomeParentOf(withClause4);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(documentationComment, visitor);
@@ -1739,8 +1881,14 @@
    * @param comment the documentation comment associated with this member
    * @param metadata the annotations associated with this member
    */
-  ClassMember(Comment comment, List<Annotation> metadata) : super(comment, metadata) {
+  ClassMember.full(Comment comment, List<Annotation> metadata) : super.full(comment, metadata) {
   }
+  /**
+   * Initialize a newly created member of a class.
+   * @param comment the documentation comment associated with this member
+   * @param metadata the annotations associated with this member
+   */
+  ClassMember({Comment comment, List<Annotation> metadata}) : this.full(comment, metadata);
 }
 /**
  * Instances of the class {@code ClassTypeAlias} represent a class type alias.
@@ -1794,7 +1942,7 @@
    * @param implementsClause the implements clause for this class
    * @param semicolon the semicolon terminating the declaration
    */
-  ClassTypeAlias(Comment comment, List<Annotation> metadata, Token keyword, SimpleIdentifier name, TypeParameterList typeParameters, Token equals, Token abstractKeyword, TypeName superclass, WithClause withClause, ImplementsClause implementsClause, Token semicolon) : super(comment, metadata, keyword, semicolon) {
+  ClassTypeAlias.full(Comment comment, List<Annotation> metadata, Token keyword, SimpleIdentifier name, TypeParameterList typeParameters, Token equals, Token abstractKeyword, TypeName superclass, WithClause withClause, ImplementsClause implementsClause, Token semicolon) : super.full(comment, metadata, keyword, semicolon) {
     this._name = becomeParentOf(name);
     this._typeParameters = becomeParentOf(typeParameters);
     this._equals = equals;
@@ -1803,6 +1951,21 @@
     this._withClause = becomeParentOf(withClause);
     this._implementsClause = becomeParentOf(implementsClause);
   }
+  /**
+   * Initialize a newly created class type alias.
+   * @param comment the documentation comment associated with this type alias
+   * @param metadata the annotations associated with this type alias
+   * @param keyword the token representing the 'typedef' keyword
+   * @param name the name of the class being declared
+   * @param typeParameters the type parameters for the class
+   * @param equals the token for the '=' separating the name from the definition
+   * @param abstractKeyword the token for the 'abstract' keyword
+   * @param superclass the name of the superclass of the class being declared
+   * @param withClause the with clause for this class
+   * @param implementsClause the implements clause for this class
+   * @param semicolon the semicolon terminating the declaration
+   */
+  ClassTypeAlias({Comment comment, List<Annotation> metadata, Token keyword, SimpleIdentifier name, TypeParameterList typeParameters, Token equals, Token abstractKeyword, TypeName superclass, WithClause withClause, ImplementsClause implementsClause, Token semicolon}) : this.full(comment, metadata, keyword, name, typeParameters, equals, abstractKeyword, superclass, withClause, implementsClause, semicolon);
   accept(ASTVisitor visitor) => visitor.visitClassTypeAlias(this);
   /**
    * Return the token for the 'abstract' keyword, or {@code null} if this is not defining an
@@ -1815,7 +1978,7 @@
    * structure has not been resolved.
    * @return the {@link ClassElement} associated with this type alias
    */
-  ClassElement get element => _name != null ? _name.element as ClassElement : null;
+  ClassElement get element => _name != null ? (_name.element as ClassElement) : null;
   /**
    * Return the token for the '=' separating the name from the definition.
    * @return the token for the '=' separating the name from the definition
@@ -1851,50 +2014,50 @@
    * Set the token for the 'abstract' keyword to the given token.
    * @param abstractKeyword the token for the 'abstract' keyword
    */
-  void set abstractKeyword3(Token abstractKeyword) {
-    this._abstractKeyword = abstractKeyword;
+  void set abstractKeyword(Token abstractKeyword3) {
+    this._abstractKeyword = abstractKeyword3;
   }
   /**
    * Set the token for the '=' separating the name from the definition to the given token.
    * @param equals the token for the '=' separating the name from the definition
    */
-  void set equals4(Token equals) {
-    this._equals = equals;
+  void set equals(Token equals4) {
+    this._equals = equals4;
   }
   /**
    * Set the implements clause for this class to the given implements clause.
    * @param implementsClause the implements clause for this class
    */
-  void set implementsClause3(ImplementsClause implementsClause) {
-    this._implementsClause = becomeParentOf(implementsClause);
+  void set implementsClause(ImplementsClause implementsClause5) {
+    this._implementsClause = becomeParentOf(implementsClause5);
   }
   /**
    * Set the name of the class being declared to the given identifier.
    * @param name the name of the class being declared
    */
-  void set name4(SimpleIdentifier name) {
-    this._name = becomeParentOf(name);
+  void set name(SimpleIdentifier name3) {
+    this._name = becomeParentOf(name3);
   }
   /**
    * Set the name of the superclass of the class being declared to the given name.
    * @param superclass the name of the superclass of the class being declared
    */
-  void set superclass2(TypeName superclass) {
-    this._superclass = becomeParentOf(superclass);
+  void set superclass(TypeName superclass2) {
+    this._superclass = becomeParentOf(superclass2);
   }
   /**
    * Set the type parameters for the class to the given list of parameters.
    * @param typeParameters the type parameters for the class
    */
-  void set typeParameters3(TypeParameterList typeParameters) {
-    this._typeParameters = becomeParentOf(typeParameters);
+  void set typeParameters(TypeParameterList typeParameters3) {
+    this._typeParameters = becomeParentOf(typeParameters3);
   }
   /**
    * Set the with clause for this class to the given with clause.
    * @param withClause the with clause for this class
    */
-  void set withClause3(WithClause withClause) {
-    this._withClause = becomeParentOf(withClause);
+  void set withClause(WithClause withClause5) {
+    this._withClause = becomeParentOf(withClause5);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     super.visitChildren(visitor);
@@ -1921,9 +2084,15 @@
    * @param keyword the keyword specifying what kind of processing is to be done on the imported
    * names
    */
-  Combinator(Token keyword) {
+  Combinator.full(Token keyword) {
     this._keyword = keyword;
   }
+  /**
+   * Initialize a newly created import combinator.
+   * @param keyword the keyword specifying what kind of processing is to be done on the imported
+   * names
+   */
+  Combinator({Token keyword}) : this.full(keyword);
   Token get beginToken => _keyword;
   /**
    * Return the keyword specifying what kind of processing is to be done on the imported names.
@@ -1936,8 +2105,8 @@
    * @param keyword the keyword specifying what kind of processing is to be done on the imported
    * names
    */
-  void set keyword5(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword5) {
+    this._keyword = keyword5;
   }
 }
 /**
@@ -1962,26 +2131,26 @@
    * @param tokens the tokens representing the comment
    * @return the block comment that was created
    */
-  static Comment createBlockComment(List<Token> tokens) => new Comment(tokens, CommentType.BLOCK, null);
+  static Comment createBlockComment(List<Token> tokens) => new Comment.full(tokens, CommentType.BLOCK, null);
   /**
    * Create a documentation comment.
    * @param tokens the tokens representing the comment
    * @return the documentation comment that was created
    */
-  static Comment createDocumentationComment(List<Token> tokens) => new Comment(tokens, CommentType.DOCUMENTATION, new List<CommentReference>());
+  static Comment createDocumentationComment(List<Token> tokens) => new Comment.full(tokens, CommentType.DOCUMENTATION, new List<CommentReference>());
   /**
    * Create a documentation comment.
    * @param tokens the tokens representing the comment
    * @param references the references embedded within the documentation comment
    * @return the documentation comment that was created
    */
-  static Comment createDocumentationComment2(List<Token> tokens, List<CommentReference> references) => new Comment(tokens, CommentType.DOCUMENTATION, references);
+  static Comment createDocumentationComment2(List<Token> tokens, List<CommentReference> references) => new Comment.full(tokens, CommentType.DOCUMENTATION, references);
   /**
    * Create an end-of-line comment.
    * @param tokens the tokens representing the comment
    * @return the end-of-line comment that was created
    */
-  static Comment createEndOfLineComment(List<Token> tokens) => new Comment(tokens, CommentType.END_OF_LINE, null);
+  static Comment createEndOfLineComment(List<Token> tokens) => new Comment.full(tokens, CommentType.END_OF_LINE, null);
   /**
    * The tokens representing the comment.
    */
@@ -2001,12 +2170,19 @@
    * @param type the type of the comment
    * @param references the references embedded within the documentation comment
    */
-  Comment(List<Token> tokens, CommentType type, List<CommentReference> references) {
+  Comment.full(List<Token> tokens, CommentType type, List<CommentReference> references) {
     this._references = new NodeList<CommentReference>(this);
     this._tokens = tokens;
     this._type = type;
     this._references.addAll(references);
   }
+  /**
+   * Initialize a newly created comment.
+   * @param tokens the tokens representing the comment
+   * @param type the type of the comment
+   * @param references the references embedded within the documentation comment
+   */
+  Comment({List<Token> tokens, CommentType type, List<CommentReference> references}) : this.full(tokens, type, references);
   accept(ASTVisitor visitor) => visitor.visitComment(this);
   Token get beginToken => _tokens[0];
   Token get endToken => _tokens[_tokens.length - 1];
@@ -2019,17 +2195,17 @@
    * Return {@code true} if this is a block comment.
    * @return {@code true} if this is a block comment
    */
-  bool isBlock() => _type == CommentType.BLOCK;
+  bool isBlock() => identical(_type, CommentType.BLOCK);
   /**
    * Return {@code true} if this is a documentation comment.
    * @return {@code true} if this is a documentation comment
    */
-  bool isDocumentation() => _type == CommentType.DOCUMENTATION;
+  bool isDocumentation() => identical(_type, CommentType.DOCUMENTATION);
   /**
    * Return {@code true} if this is an end-of-line comment.
    * @return {@code true} if this is an end-of-line comment
    */
-  bool isEndOfLine() => _type == CommentType.END_OF_LINE;
+  bool isEndOfLine() => identical(_type, CommentType.END_OF_LINE);
   void visitChildren(ASTVisitor<Object> visitor) {
     _references.accept(visitor);
   }
@@ -2080,10 +2256,16 @@
    * @param newKeyword the token representing the 'new' keyword
    * @param identifier the identifier being referenced
    */
-  CommentReference(Token newKeyword, Identifier identifier) {
+  CommentReference.full(Token newKeyword, Identifier identifier) {
     this._newKeyword = newKeyword;
     this._identifier = becomeParentOf(identifier);
   }
+  /**
+   * Initialize a newly created reference to a Dart element.
+   * @param newKeyword the token representing the 'new' keyword
+   * @param identifier the identifier being referenced
+   */
+  CommentReference({Token newKeyword, Identifier identifier}) : this.full(newKeyword, identifier);
   accept(ASTVisitor visitor) => visitor.visitCommentReference(this);
   Token get beginToken => _identifier.beginToken;
   Token get endToken => _identifier.endToken;
@@ -2101,15 +2283,15 @@
    * Set the identifier being referenced to the given identifier.
    * @param identifier the identifier being referenced
    */
-  void set identifier3(Identifier identifier) {
-    identifier = becomeParentOf(identifier);
+  void set identifier(Identifier identifier18) {
+    identifier18 = becomeParentOf(identifier18);
   }
   /**
    * Set the token representing the 'new' keyword to the given token.
    * @param newKeyword the token representing the 'new' keyword
    */
-  void set newKeyword2(Token newKeyword) {
-    this._newKeyword = newKeyword;
+  void set newKeyword(Token newKeyword2) {
+    this._newKeyword = newKeyword2;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_identifier, visitor);
@@ -2156,9 +2338,17 @@
    */
   CompilationUnitElement _element;
   /**
-   * The syntax errors encountered when the receiver was parsed.
+   * The {@link LineInfo} for this {@link CompilationUnit}.
    */
-  List<AnalysisError> _syntacticErrors;
+  LineInfo _lineInfo;
+  /**
+   * The parsing errors encountered when the receiver was parsed.
+   */
+  List<AnalysisError> _parsingErrors = AnalysisError.NO_ERRORS;
+  /**
+   * The resolution errors encountered when the receiver was resolved.
+   */
+  List<AnalysisError> _resolutionErrors = AnalysisError.NO_ERRORS;
   /**
    * Initialize a newly created compilation unit to have the given directives and declarations.
    * @param beginToken the first token in the token stream
@@ -2167,7 +2357,7 @@
    * @param declarations the declarations contained in this compilation unit
    * @param endToken the last token in the token stream
    */
-  CompilationUnit(Token beginToken, ScriptTag scriptTag, List<Directive> directives, List<CompilationUnitMember> declarations, Token endToken) {
+  CompilationUnit.full(Token beginToken, ScriptTag scriptTag, List<Directive> directives, List<CompilationUnitMember> declarations, Token endToken) {
     this._directives = new NodeList<Directive>(this);
     this._declarations = new NodeList<CompilationUnitMember>(this);
     this._beginToken = beginToken;
@@ -2176,6 +2366,15 @@
     this._declarations.addAll(declarations);
     this._endToken = endToken;
   }
+  /**
+   * Initialize a newly created compilation unit to have the given directives and declarations.
+   * @param beginToken the first token in the token stream
+   * @param scriptTag the script tag at the beginning of the compilation unit
+   * @param directives the directives contained in this compilation unit
+   * @param declarations the declarations contained in this compilation unit
+   * @param endToken the last token in the token stream
+   */
+  CompilationUnit({Token beginToken, ScriptTag scriptTag, List<Directive> directives, List<CompilationUnitMember> declarations, Token endToken}) : this.full(beginToken, scriptTag, directives, declarations, endToken);
   accept(ASTVisitor visitor) => visitor.visitCompilationUnit(this);
   Token get beginToken => _beginToken;
   /**
@@ -2202,15 +2401,31 @@
    * been resolved
    */
   List<AnalysisError> get errors {
-    throw new UnsupportedOperationException();
+    List<AnalysisError> parserErrors = parsingErrors;
+    List<AnalysisError> resolverErrors = resolutionErrors;
+    if (resolverErrors.length == 0) {
+      return parserErrors;
+    } else if (parserErrors.length == 0) {
+      return resolverErrors;
+    } else {
+      List<AnalysisError> allErrors = new List<AnalysisError>.fixedLength(parserErrors.length + resolverErrors.length);
+      System.arraycopy(parserErrors, 0, allErrors, 0, parserErrors.length);
+      System.arraycopy(resolverErrors, 0, allErrors, parserErrors.length, resolverErrors.length);
+      return allErrors;
+    }
   }
   int get length {
-    Token endToken4 = endToken;
-    if (endToken4 == null) {
+    Token endToken3 = endToken;
+    if (endToken3 == null) {
       return 0;
     }
-    return endToken4.offset + endToken4.length - beginToken.offset;
+    return endToken3.offset + endToken3.length - beginToken.offset;
   }
+  /**
+   * Get the {@link LineInfo} object for this compilation unit.
+   * @return the associated {@link LineInfo}
+   */
+  LineInfo get lineInfo => _lineInfo;
   int get offset {
     Token beginToken4 = beginToken;
     if (beginToken4 == null) {
@@ -2219,45 +2434,59 @@
     return beginToken4.offset;
   }
   /**
+   * Return an array containing all of the parsing errors associated with the receiver.
+   * @return an array of errors (not {@code null}, contains no {@code null}s).
+   */
+  List<AnalysisError> get parsingErrors => _parsingErrors;
+  /**
+   * Return an array containing all of the resolution errors associated with the receiver. If the
+   * receiver has not been resolved, then return {@code null}.
+   * @return an array of errors (contains no {@code null}s) or {@code null} if the receiver has not
+   * been resolved
+   */
+  List<AnalysisError> get resolutionErrors => _resolutionErrors;
+  /**
    * Return the script tag at the beginning of the compilation unit, or {@code null} if there is no
    * script tag in this compilation unit.
    * @return the script tag at the beginning of the compilation unit
    */
   ScriptTag get scriptTag => _scriptTag;
   /**
-   * Return an array containing all of the semantic errors associated with the receiver. If the
-   * receiver has not been resolved, then return {@code null}.
-   * @return an array of errors (contains no {@code null}s) or {@code null} if the receiver has not
-   * been resolved
-   */
-  List<AnalysisError> get semanticErrors {
-    throw new UnsupportedOperationException();
-  }
-  /**
-   * Return an array containing all of the syntactic errors associated with the receiver.
-   * @return an array of errors (not {@code null}, contains no {@code null}s).
-   */
-  List<AnalysisError> get syntacticErrors => _syntacticErrors;
-  /**
    * Set the element associated with this compilation unit to the given element.
    * @param element the element associated with this compilation unit
    */
-  void set element4(CompilationUnitElement element) {
-    this._element = element;
+  void set element(CompilationUnitElement element5) {
+    this._element = element5;
+  }
+  /**
+   * Set the {@link LineInfo} object for this compilation unit.
+   * @param errors LineInfo to associate with this compilation unit
+   */
+  void set lineInfo(LineInfo lineInfo2) {
+    this._lineInfo = lineInfo2;
+  }
+  /**
+   * Called to cache the parsing errors when the unit is parsed.
+   * @param errors an array of parsing errors, if <code>null</code> is passed, the error array is
+   * set to an empty array, {@link AnalysisError#NO_ERRORS}
+   */
+  void set parsingErrors(List<AnalysisError> errors) {
+    _parsingErrors = errors == null ? AnalysisError.NO_ERRORS : errors;
+  }
+  /**
+   * Called to cache the resolution errors when the unit is resolved.
+   * @param errors an array of resolution errors, if <code>null</code> is passed, the error array is
+   * set to an empty array, {@link AnalysisError#NO_ERRORS}
+   */
+  void set resolutionErrors(List<AnalysisError> errors) {
+    _resolutionErrors = errors == null ? AnalysisError.NO_ERRORS : errors;
   }
   /**
    * Set the script tag at the beginning of the compilation unit to the given script tag.
    * @param scriptTag the script tag at the beginning of the compilation unit
    */
-  void set scriptTag2(ScriptTag scriptTag) {
-    this._scriptTag = becomeParentOf(scriptTag);
-  }
-  /**
-   * Called by the {@link AnalysisContext} to cache the syntax errors when the unit is parsed.
-   * @param errors an array of syntax errors (not {@code null}, contains no {@code null}s)
-   */
-  void set syntacticErrors2(List<AnalysisError> errors) {
-    this._syntacticErrors = errors;
+  void set scriptTag(ScriptTag scriptTag2) {
+    this._scriptTag = becomeParentOf(scriptTag2);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_scriptTag, visitor);
@@ -2309,8 +2538,14 @@
    * @param comment the documentation comment associated with this member
    * @param metadata the annotations associated with this member
    */
-  CompilationUnitMember(Comment comment, List<Annotation> metadata) : super(comment, metadata) {
+  CompilationUnitMember.full(Comment comment, List<Annotation> metadata) : super.full(comment, metadata) {
   }
+  /**
+   * Initialize a newly created generic compilation unit member.
+   * @param comment the documentation comment associated with this member
+   * @param metadata the annotations associated with this member
+   */
+  CompilationUnitMember({Comment comment, List<Annotation> metadata}) : this.full(comment, metadata);
 }
 /**
  * Instances of the class {@code ConditionalExpression} represent a conditional expression.
@@ -2346,13 +2581,22 @@
    * @param colon the token used to separate the then expression from the else expression
    * @param elseExpression the expression that is executed if the condition evaluates to{@code false}
    */
-  ConditionalExpression(Expression condition, Token question, Expression thenExpression, Token colon, Expression elseExpression) {
+  ConditionalExpression.full(Expression condition, Token question, Expression thenExpression, Token colon, Expression elseExpression) {
     this._condition = becomeParentOf(condition);
     this._question = question;
     this._thenExpression = becomeParentOf(thenExpression);
     this._colon = colon;
     this._elseExpression = becomeParentOf(elseExpression);
   }
+  /**
+   * Initialize a newly created conditional expression.
+   * @param condition the condition used to determine which expression is executed next
+   * @param question the token used to separate the condition from the then expression
+   * @param thenExpression the expression that is executed if the condition evaluates to{@code true}
+   * @param colon the token used to separate the then expression from the else expression
+   * @param elseExpression the expression that is executed if the condition evaluates to{@code false}
+   */
+  ConditionalExpression({Expression condition, Token question, Expression thenExpression, Token colon, Expression elseExpression}) : this.full(condition, question, thenExpression, colon, elseExpression);
   accept(ASTVisitor visitor) => visitor.visitConditionalExpression(this);
   Token get beginToken => _condition.beginToken;
   /**
@@ -2385,15 +2629,15 @@
    * Set the token used to separate the then expression from the else expression to the given token.
    * @param colon the token used to separate the then expression from the else expression
    */
-  void set colon2(Token colon) {
-    this._colon = colon;
+  void set colon(Token colon2) {
+    this._colon = colon2;
   }
   /**
    * Set the condition used to determine which of the expressions is executed next to the given
    * expression.
    * @param expression the condition used to determine which expression is executed next
    */
-  void set condition3(Expression expression) {
+  void set condition(Expression expression) {
     _condition = becomeParentOf(expression);
   }
   /**
@@ -2401,22 +2645,22 @@
    * expression.
    * @param expression the expression that is executed if the condition evaluates to {@code false}
    */
-  void set elseExpression2(Expression expression) {
+  void set elseExpression(Expression expression) {
     _elseExpression = becomeParentOf(expression);
   }
   /**
    * Set the token used to separate the condition from the then expression to the given token.
    * @param question the token used to separate the condition from the then expression
    */
-  void set question3(Token question) {
-    this._question = question;
+  void set question(Token question3) {
+    this._question = question3;
   }
   /**
    * Set the expression that is executed if the condition evaluates to {@code true} to the given
    * expression.
    * @param expression the expression that is executed if the condition evaluates to {@code true}
    */
-  void set thenExpression2(Expression expression) {
+  void set thenExpression(Expression expression) {
     _thenExpression = becomeParentOf(expression);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -2512,7 +2756,7 @@
    * redirected
    * @param body the body of the constructor
    */
-  ConstructorDeclaration(Comment comment, List<Annotation> metadata, Token externalKeyword, Token constKeyword, Token factoryKeyword, Identifier returnType, Token period, SimpleIdentifier name, FormalParameterList parameters, Token separator, List<ConstructorInitializer> initializers, ConstructorName redirectedConstructor, FunctionBody body) : super(comment, metadata) {
+  ConstructorDeclaration.full(Comment comment, List<Annotation> metadata, Token externalKeyword, Token constKeyword, Token factoryKeyword, Identifier returnType, Token period, SimpleIdentifier name, FormalParameterList parameters, Token separator, List<ConstructorInitializer> initializers, ConstructorName redirectedConstructor, FunctionBody body) : super.full(comment, metadata) {
     this._initializers = new NodeList<ConstructorInitializer>(this);
     this._externalKeyword = externalKeyword;
     this._constKeyword = constKeyword;
@@ -2526,6 +2770,24 @@
     this._redirectedConstructor = becomeParentOf(redirectedConstructor);
     this._body = becomeParentOf(body);
   }
+  /**
+   * Initialize a newly created constructor declaration.
+   * @param externalKeyword the token for the 'external' keyword
+   * @param comment the documentation comment associated with this constructor
+   * @param metadata the annotations associated with this constructor
+   * @param constKeyword the token for the 'const' keyword
+   * @param factoryKeyword the token for the 'factory' keyword
+   * @param returnType the return type of the constructor
+   * @param period the token for the period before the constructor name
+   * @param name the name of the constructor
+   * @param parameters the parameters associated with the constructor
+   * @param separator the token for the colon or equals before the initializers
+   * @param initializers the initializers associated with the constructor
+   * @param redirectedConstructor the name of the constructor to which this constructor will be
+   * redirected
+   * @param body the body of the constructor
+   */
+  ConstructorDeclaration({Comment comment, List<Annotation> metadata, Token externalKeyword, Token constKeyword, Token factoryKeyword, Identifier returnType, Token period, SimpleIdentifier name, FormalParameterList parameters, Token separator, List<ConstructorInitializer> initializers, ConstructorName redirectedConstructor, FunctionBody body}) : this.full(comment, metadata, externalKeyword, constKeyword, factoryKeyword, returnType, period, name, parameters, separator, initializers, redirectedConstructor, body);
   accept(ASTVisitor visitor) => visitor.visitConstructorDeclaration(this);
   /**
    * Return the body of the constructor, or {@code null} if the constructor does not have a body.
@@ -2605,57 +2867,57 @@
    * Set the body of the constructor to the given function body.
    * @param functionBody the body of the constructor
    */
-  void set body3(FunctionBody functionBody) {
+  void set body(FunctionBody functionBody) {
     _body = becomeParentOf(functionBody);
   }
   /**
    * Set the token for the 'const' keyword to the given token.
    * @param constKeyword the token for the 'const' keyword
    */
-  void set constKeyword2(Token constKeyword) {
-    this._constKeyword = constKeyword;
+  void set constKeyword(Token constKeyword2) {
+    this._constKeyword = constKeyword2;
   }
   /**
    * Set the element associated with this constructor to the given element.
    * @param element the element associated with this constructor
    */
-  void set element5(ConstructorElement element) {
-    this._element = element;
+  void set element(ConstructorElement element6) {
+    this._element = element6;
   }
   /**
    * Set the token for the 'external' keyword to the given token.
    * @param externalKeyword the token for the 'external' keyword
    */
-  void set externalKeyword2(Token externalKeyword) {
-    this._externalKeyword = externalKeyword;
+  void set externalKeyword(Token externalKeyword2) {
+    this._externalKeyword = externalKeyword2;
   }
   /**
    * Set the token for the 'factory' keyword to the given token.
    * @param factoryKeyword the token for the 'factory' keyword
    */
-  void set factoryKeyword2(Token factoryKeyword) {
-    this._factoryKeyword = factoryKeyword;
+  void set factoryKeyword(Token factoryKeyword2) {
+    this._factoryKeyword = factoryKeyword2;
   }
   /**
    * Set the name of the constructor to the given identifier.
    * @param identifier the name of the constructor
    */
-  void set name5(SimpleIdentifier identifier) {
+  void set name(SimpleIdentifier identifier) {
     _name = becomeParentOf(identifier);
   }
   /**
    * Set the parameters associated with the constructor to the given list of parameters.
    * @param parameters the parameters associated with the constructor
    */
-  void set parameters2(FormalParameterList parameters) {
-    this._parameters = becomeParentOf(parameters);
+  void set parameters(FormalParameterList parameters2) {
+    this._parameters = becomeParentOf(parameters2);
   }
   /**
    * Set the token for the period before the constructor name to the given token.
    * @param period the token for the period before the constructor name
    */
-  void set period3(Token period) {
-    this._period = period;
+  void set period(Token period3) {
+    this._period = period3;
   }
   /**
    * Set the name of the constructor to which this constructor will be redirected to the given
@@ -2663,22 +2925,22 @@
    * @param redirectedConstructor the name of the constructor to which this constructor will be
    * redirected
    */
-  void set redirectedConstructor2(ConstructorName redirectedConstructor) {
-    this._redirectedConstructor = becomeParentOf(redirectedConstructor);
+  void set redirectedConstructor(ConstructorName redirectedConstructor2) {
+    this._redirectedConstructor = becomeParentOf(redirectedConstructor2);
   }
   /**
    * Set the type of object being created to the given type name.
    * @param typeName the type of object being created
    */
-  void set returnType2(Identifier typeName) {
+  void set returnType(Identifier typeName) {
     _returnType = becomeParentOf(typeName);
   }
   /**
    * Set the token for the separator (colon or equals) before the initializers to the given token.
    * @param separator the token for the separator (colon or equals) before the initializers
    */
-  void set separator2(Token separator) {
-    this._separator = separator;
+  void set separator(Token separator2) {
+    this._separator = separator2;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     super.visitChildren(visitor);
@@ -2750,13 +3012,23 @@
    * @param equals the token for the equal sign between the field name and the expression
    * @param expression the expression computing the value to which the field will be initialized
    */
-  ConstructorFieldInitializer(Token keyword, Token period, SimpleIdentifier fieldName, Token equals, Expression expression) {
+  ConstructorFieldInitializer.full(Token keyword, Token period, SimpleIdentifier fieldName, Token equals, Expression expression) {
     this._keyword = keyword;
     this._period = period;
     this._fieldName = becomeParentOf(fieldName);
     this._equals = equals;
     this._expression = becomeParentOf(expression);
   }
+  /**
+   * Initialize a newly created field initializer to initialize the field with the given name to the
+   * value of the given expression.
+   * @param keyword the token for the 'this' keyword
+   * @param period the token for the period after the 'this' keyword
+   * @param fieldName the name of the field being initialized
+   * @param equals the token for the equal sign between the field name and the expression
+   * @param expression the expression computing the value to which the field will be initialized
+   */
+  ConstructorFieldInitializer({Token keyword, Token period, SimpleIdentifier fieldName, Token equals, Expression expression}) : this.full(keyword, period, fieldName, equals, expression);
   accept(ASTVisitor visitor) => visitor.visitConstructorFieldInitializer(this);
   Token get beginToken {
     if (_keyword != null) {
@@ -2795,37 +3067,37 @@
    * Set the token for the equal sign between the field name and the expression to the given token.
    * @param equals the token for the equal sign between the field name and the expression
    */
-  void set equals5(Token equals) {
-    this._equals = equals;
+  void set equals(Token equals5) {
+    this._equals = equals5;
   }
   /**
    * Set the expression computing the value to which the field will be initialized to the given
    * expression.
    * @param expression the expression computing the value to which the field will be initialized
    */
-  void set expression3(Expression expression) {
-    this._expression = becomeParentOf(expression);
+  void set expression(Expression expression3) {
+    this._expression = becomeParentOf(expression3);
   }
   /**
    * Set the name of the field being initialized to the given identifier.
    * @param identifier the name of the field being initialized
    */
-  void set fieldName2(SimpleIdentifier identifier) {
+  void set fieldName(SimpleIdentifier identifier) {
     _fieldName = becomeParentOf(identifier);
   }
   /**
    * Set the token for the 'this' keyword to the given token.
    * @param keyword the token for the 'this' keyword
    */
-  void set keyword6(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword6) {
+    this._keyword = keyword6;
   }
   /**
    * Set the token for the period after the 'this' keyword to the given token.
    * @param period the token for the period after the 'this' keyword
    */
-  void set period4(Token period) {
-    this._period = period;
+  void set period(Token period4) {
+    this._period = period4;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_fieldName, visitor);
@@ -2873,11 +3145,18 @@
    * @param period the token for the period before the constructor name
    * @param name the name of the constructor
    */
-  ConstructorName(TypeName type, Token period, SimpleIdentifier name) {
+  ConstructorName.full(TypeName type, Token period, SimpleIdentifier name) {
     this._type = becomeParentOf(type);
     this._period = period;
     this._name = becomeParentOf(name);
   }
+  /**
+   * Initialize a newly created constructor name.
+   * @param type the name of the type defining the constructor
+   * @param period the token for the period before the constructor name
+   * @param name the name of the constructor
+   */
+  ConstructorName({TypeName type, Token period, SimpleIdentifier name}) : this.full(type, period, name);
   accept(ASTVisitor visitor) => visitor.visitConstructorName(this);
   Token get beginToken => _type.beginToken;
   /**
@@ -2913,29 +3192,29 @@
    * Set the element associated with this constructor name to the given element.
    * @param element the element associated with this constructor name
    */
-  void set element6(ConstructorElement element) {
-    this._element = element;
+  void set element(ConstructorElement element7) {
+    this._element = element7;
   }
   /**
    * Set the name of the constructor to the given name.
    * @param name the name of the constructor
    */
-  void set name6(SimpleIdentifier name) {
-    this._name = becomeParentOf(name);
+  void set name(SimpleIdentifier name4) {
+    this._name = becomeParentOf(name4);
   }
   /**
    * Return the token for the period before the constructor name to the given token.
    * @param period the token for the period before the constructor name
    */
-  void set period5(Token period) {
-    this._period = period;
+  void set period(Token period5) {
+    this._period = period5;
   }
   /**
    * Set the name of the type defining the constructor to the given type name.
    * @param type the name of the type defining the constructor
    */
-  void set type3(TypeName type) {
-    this._type = becomeParentOf(type);
+  void set type(TypeName type2) {
+    this._type = becomeParentOf(type2);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_type, visitor);
@@ -2968,11 +3247,18 @@
    * @param label the label associated with the statement
    * @param semicolon the semicolon terminating the statement
    */
-  ContinueStatement(Token keyword, SimpleIdentifier label, Token semicolon) {
+  ContinueStatement.full(Token keyword, SimpleIdentifier label, Token semicolon) {
     this._keyword = keyword;
     this._label = becomeParentOf(label);
     this._semicolon = semicolon;
   }
+  /**
+   * Initialize a newly created continue statement.
+   * @param keyword the token representing the 'continue' keyword
+   * @param label the label associated with the statement
+   * @param semicolon the semicolon terminating the statement
+   */
+  ContinueStatement({Token keyword, SimpleIdentifier label, Token semicolon}) : this.full(keyword, label, semicolon);
   accept(ASTVisitor visitor) => visitor.visitContinueStatement(this);
   Token get beginToken => _keyword;
   Token get endToken => _semicolon;
@@ -2995,22 +3281,22 @@
    * Set the token representing the 'continue' keyword to the given token.
    * @param keyword the token representing the 'continue' keyword
    */
-  void set keyword7(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword7) {
+    this._keyword = keyword7;
   }
   /**
    * Set the label associated with the statement to the given label.
    * @param identifier the label associated with the statement
    */
-  void set label3(SimpleIdentifier identifier) {
+  void set label(SimpleIdentifier identifier) {
     _label = becomeParentOf(identifier);
   }
   /**
    * Set the semicolon terminating the statement to the given token.
    * @param semicolon the semicolon terminating the statement
    */
-  void set semicolon4(Token semicolon) {
-    this._semicolon = semicolon;
+  void set semicolon(Token semicolon4) {
+    this._semicolon = semicolon4;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_label, visitor);
@@ -3026,8 +3312,14 @@
    * @param comment the documentation comment associated with this declaration
    * @param metadata the annotations associated with this declaration
    */
-  Declaration(Comment comment, List<Annotation> metadata) : super(comment, metadata) {
+  Declaration.full(Comment comment, List<Annotation> metadata) : super.full(comment, metadata) {
   }
+  /**
+   * Initialize a newly created declaration.
+   * @param comment the documentation comment associated with this declaration
+   * @param metadata the annotations associated with this declaration
+   */
+  Declaration({Comment comment, List<Annotation> metadata}) : this.full(comment, metadata);
 }
 /**
  * Instances of the class {@code DefaultFormalParameter} represent a formal parameter with a default
@@ -3064,12 +3356,20 @@
    * @param separator the token separating the parameter from the default value
    * @param defaultValue the expression computing the default value for the parameter
    */
-  DefaultFormalParameter(NormalFormalParameter parameter, ParameterKind kind, Token separator, Expression defaultValue) {
+  DefaultFormalParameter.full(NormalFormalParameter parameter, ParameterKind kind, Token separator, Expression defaultValue) {
     this._parameter = becomeParentOf(parameter);
     this._kind = kind;
     this._separator = separator;
     this._defaultValue = becomeParentOf(defaultValue);
   }
+  /**
+   * Initialize a newly created default formal parameter.
+   * @param parameter the formal parameter with which the default value is associated
+   * @param kind the kind of this parameter
+   * @param separator the token separating the parameter from the default value
+   * @param defaultValue the expression computing the default value for the parameter
+   */
+  DefaultFormalParameter({NormalFormalParameter parameter, ParameterKind kind, Token separator, Expression defaultValue}) : this.full(parameter, kind, separator, defaultValue);
   accept(ASTVisitor visitor) => visitor.visitDefaultFormalParameter(this);
   Token get beginToken => _parameter.beginToken;
   /**
@@ -3111,29 +3411,29 @@
    * Set the expression computing the default value for the parameter to the given expression.
    * @param expression the expression computing the default value for the parameter
    */
-  void set defaultValue2(Expression expression) {
+  void set defaultValue(Expression expression) {
     _defaultValue = becomeParentOf(expression);
   }
   /**
    * Set the kind of this parameter to the given kind.
    * @param kind the kind of this parameter
    */
-  void set kind2(ParameterKind kind) {
-    this._kind = kind;
+  void set kind(ParameterKind kind2) {
+    this._kind = kind2;
   }
   /**
    * Set the formal parameter with which the default value is associated to the given parameter.
    * @param formalParameter the formal parameter with which the default value is associated
    */
-  void set parameter2(NormalFormalParameter formalParameter) {
+  void set parameter(NormalFormalParameter formalParameter) {
     _parameter = becomeParentOf(formalParameter);
   }
   /**
    * Set the token separating the parameter from the default value to the given token.
    * @param separator the token separating the parameter from the default value
    */
-  void set separator3(Token separator) {
-    this._separator = separator;
+  void set separator(Token separator3) {
+    this._separator = separator3;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_parameter, visitor);
@@ -3157,9 +3457,15 @@
    * @param comment the documentation comment associated with this directive
    * @param metadata the annotations associated with the directive
    */
-  Directive(Comment comment, List<Annotation> metadata) : super(comment, metadata) {
+  Directive.full(Comment comment, List<Annotation> metadata) : super.full(comment, metadata) {
   }
   /**
+   * Initialize a newly create directive.
+   * @param comment the documentation comment associated with this directive
+   * @param metadata the annotations associated with the directive
+   */
+  Directive({Comment comment, List<Annotation> metadata}) : this.full(comment, metadata);
+  /**
    * Return the element associated with this directive, or {@code null} if the AST structure has not
    * been resolved or if this directive could not be resolved. Examples of the latter case include a
    * directive that contains an invalid URL or a URL that does not exist.
@@ -3176,8 +3482,8 @@
    * Set the element associated with this directive to the given element.
    * @param element the element associated with this directive
    */
-  void set element7(Element element) {
-    this._element = element;
+  void set element(Element element8) {
+    this._element = element8;
   }
 }
 /**
@@ -3226,7 +3532,7 @@
    * @param rightParenthesis the right parenthesis
    * @param semicolon the semicolon terminating the statement
    */
-  DoStatement(Token doKeyword, Statement body, Token whileKeyword, Token leftParenthesis, Expression condition, Token rightParenthesis, Token semicolon) {
+  DoStatement.full(Token doKeyword, Statement body, Token whileKeyword, Token leftParenthesis, Expression condition, Token rightParenthesis, Token semicolon) {
     this._doKeyword = doKeyword;
     this._body = becomeParentOf(body);
     this._whileKeyword = whileKeyword;
@@ -3235,6 +3541,17 @@
     this._rightParenthesis = rightParenthesis;
     this._semicolon = semicolon;
   }
+  /**
+   * Initialize a newly created do loop.
+   * @param doKeyword the token representing the 'do' keyword
+   * @param body the body of the loop
+   * @param whileKeyword the token representing the 'while' keyword
+   * @param leftParenthesis the left parenthesis
+   * @param condition the condition that determines when the loop will terminate
+   * @param rightParenthesis the right parenthesis
+   * @param semicolon the semicolon terminating the statement
+   */
+  DoStatement({Token doKeyword, Statement body, Token whileKeyword, Token leftParenthesis, Expression condition, Token rightParenthesis, Token semicolon}) : this.full(doKeyword, body, whileKeyword, leftParenthesis, condition, rightParenthesis, semicolon);
   accept(ASTVisitor visitor) => visitor.visitDoStatement(this);
   Token get beginToken => _doKeyword;
   /**
@@ -3277,50 +3594,50 @@
    * Set the body of the loop to the given statement.
    * @param statement the body of the loop
    */
-  void set body4(Statement statement) {
+  void set body(Statement statement) {
     _body = becomeParentOf(statement);
   }
   /**
    * Set the condition that determines when the loop will terminate to the given expression.
    * @param expression the condition that determines when the loop will terminate
    */
-  void set condition4(Expression expression) {
+  void set condition(Expression expression) {
     _condition = becomeParentOf(expression);
   }
   /**
    * Set the token representing the 'do' keyword to the given token.
    * @param doKeyword the token representing the 'do' keyword
    */
-  void set doKeyword2(Token doKeyword) {
-    this._doKeyword = doKeyword;
+  void set doKeyword(Token doKeyword2) {
+    this._doKeyword = doKeyword2;
   }
   /**
    * Set the left parenthesis to the given token.
    * @param parenthesis the left parenthesis
    */
-  void set leftParenthesis5(Token parenthesis) {
+  void set leftParenthesis(Token parenthesis) {
     _leftParenthesis = parenthesis;
   }
   /**
    * Set the right parenthesis to the given token.
    * @param parenthesis the right parenthesis
    */
-  void set rightParenthesis5(Token parenthesis) {
+  void set rightParenthesis(Token parenthesis) {
     _rightParenthesis = parenthesis;
   }
   /**
    * Set the semicolon terminating the statement to the given token.
    * @param semicolon the semicolon terminating the statement
    */
-  void set semicolon5(Token semicolon) {
-    this._semicolon = semicolon;
+  void set semicolon(Token semicolon5) {
+    this._semicolon = semicolon5;
   }
   /**
    * Set the token representing the 'while' keyword to the given token.
    * @param whileKeyword the token representing the 'while' keyword
    */
-  void set whileKeyword2(Token whileKeyword) {
-    this._whileKeyword = whileKeyword;
+  void set whileKeyword(Token whileKeyword2) {
+    this._whileKeyword = whileKeyword2;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_body, visitor);
@@ -3351,10 +3668,16 @@
    * @param literal the token representing the literal
    * @param value the value of the literal
    */
-  DoubleLiteral(Token literal, double value) {
+  DoubleLiteral.full(Token literal, double value) {
     this._literal = literal;
     this._value = value;
   }
+  /**
+   * Initialize a newly created floating point literal.
+   * @param literal the token representing the literal
+   * @param value the value of the literal
+   */
+  DoubleLiteral({Token literal, double value}) : this.full(literal, value);
   accept(ASTVisitor visitor) => visitor.visitDoubleLiteral(this);
   Token get beginToken => _literal;
   Token get endToken => _literal;
@@ -3372,15 +3695,15 @@
    * Set the token representing the literal to the given token.
    * @param literal the token representing the literal
    */
-  void set literal3(Token literal) {
-    this._literal = literal;
+  void set literal(Token literal3) {
+    this._literal = literal3;
   }
   /**
    * Set the value of the literal to the given value.
    * @param value the value of the literal
    */
-  void set value5(double value) {
-    this._value = value;
+  void set value(double value5) {
+    this._value = value5;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
   }
@@ -3402,9 +3725,14 @@
    * Initialize a newly created function body.
    * @param semicolon the token representing the semicolon that marks the end of the function body
    */
-  EmptyFunctionBody(Token semicolon) {
+  EmptyFunctionBody.full(Token semicolon) {
     this._semicolon = semicolon;
   }
+  /**
+   * Initialize a newly created function body.
+   * @param semicolon the token representing the semicolon that marks the end of the function body
+   */
+  EmptyFunctionBody({Token semicolon}) : this.full(semicolon);
   accept(ASTVisitor visitor) => visitor.visitEmptyFunctionBody(this);
   Token get beginToken => _semicolon;
   Token get endToken => _semicolon;
@@ -3418,8 +3746,8 @@
    * token.
    * @param semicolon the token representing the semicolon that marks the end of the function body
    */
-  void set semicolon6(Token semicolon) {
-    this._semicolon = semicolon;
+  void set semicolon(Token semicolon6) {
+    this._semicolon = semicolon6;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
   }
@@ -3440,9 +3768,14 @@
    * Initialize a newly created empty statement.
    * @param semicolon the semicolon terminating the statement
    */
-  EmptyStatement(Token semicolon) {
+  EmptyStatement.full(Token semicolon) {
     this._semicolon = semicolon;
   }
+  /**
+   * Initialize a newly created empty statement.
+   * @param semicolon the semicolon terminating the statement
+   */
+  EmptyStatement({Token semicolon}) : this.full(semicolon);
   accept(ASTVisitor visitor) => visitor.visitEmptyStatement(this);
   Token get beginToken => _semicolon;
   Token get endToken => _semicolon;
@@ -3455,8 +3788,8 @@
    * Set the semicolon terminating the statement to the given token.
    * @param semicolon the semicolon terminating the statement
    */
-  void set semicolon7(Token semicolon) {
-    this._semicolon = semicolon;
+  void set semicolon(Token semicolon7) {
+    this._semicolon = semicolon7;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
   }
@@ -3477,12 +3810,21 @@
    * @param combinators the combinators used to control which names are exported
    * @param semicolon the semicolon terminating the directive
    */
-  ExportDirective(Comment comment, List<Annotation> metadata, Token keyword, StringLiteral libraryUri, List<Combinator> combinators, Token semicolon) : super(comment, metadata, keyword, libraryUri, combinators, semicolon) {
+  ExportDirective.full(Comment comment, List<Annotation> metadata, Token keyword, StringLiteral libraryUri, List<Combinator> combinators, Token semicolon) : super.full(comment, metadata, keyword, libraryUri, combinators, semicolon) {
   }
+  /**
+   * Initialize a newly created export directive.
+   * @param comment the documentation comment associated with this directive
+   * @param metadata the annotations associated with the directive
+   * @param keyword the token representing the 'export' keyword
+   * @param libraryUri the URI of the library being exported
+   * @param combinators the combinators used to control which names are exported
+   * @param semicolon the semicolon terminating the directive
+   */
+  ExportDirective({Comment comment, List<Annotation> metadata, Token keyword, StringLiteral libraryUri, List<Combinator> combinators, Token semicolon}) : this.full(comment, metadata, keyword, libraryUri, combinators, semicolon);
   accept(ASTVisitor visitor) => visitor.visitExportDirective(this);
   void visitChildren(ASTVisitor<Object> visitor) {
     super.visitChildren(visitor);
-    safelyVisitChild(libraryUri, visitor);
     combinators.accept(visitor);
   }
 }
@@ -3524,15 +3866,15 @@
    * Set the propagated type of this expression to the given type.
    * @param propagatedType the propagated type of this expression
    */
-  void set propagatedType2(Type2 propagatedType) {
-    this._propagatedType = propagatedType;
+  void set propagatedType(Type2 propagatedType2) {
+    this._propagatedType = propagatedType2;
   }
   /**
    * Set the static type of this expression to the given type.
    * @param staticType the static type of this expression
    */
-  void set staticType2(Type2 staticType) {
-    this._staticType = staticType;
+  void set staticType(Type2 staticType2) {
+    this._staticType = staticType2;
   }
 }
 /**
@@ -3563,11 +3905,19 @@
    * @param expression the expression representing the body of the function
    * @param semicolon the semicolon terminating the statement
    */
-  ExpressionFunctionBody(Token functionDefinition, Expression expression, Token semicolon) {
+  ExpressionFunctionBody.full(Token functionDefinition, Expression expression, Token semicolon) {
     this._functionDefinition = functionDefinition;
     this._expression = becomeParentOf(expression);
     this._semicolon = semicolon;
   }
+  /**
+   * Initialize a newly created function body consisting of a block of statements.
+   * @param functionDefinition the token introducing the expression that represents the body of the
+   * function
+   * @param expression the expression representing the body of the function
+   * @param semicolon the semicolon terminating the statement
+   */
+  ExpressionFunctionBody({Token functionDefinition, Expression expression, Token semicolon}) : this.full(functionDefinition, expression, semicolon);
   accept(ASTVisitor visitor) => visitor.visitExpressionFunctionBody(this);
   Token get beginToken => _functionDefinition;
   Token get endToken {
@@ -3595,23 +3945,23 @@
    * Set the expression representing the body of the function to the given expression.
    * @param expression the expression representing the body of the function
    */
-  void set expression4(Expression expression) {
-    this._expression = becomeParentOf(expression);
+  void set expression(Expression expression4) {
+    this._expression = becomeParentOf(expression4);
   }
   /**
    * Set the token introducing the expression that represents the body of the function to the given
    * token.
    * @param functionDefinition the function definition token
    */
-  void set functionDefinition2(Token functionDefinition) {
-    this._functionDefinition = functionDefinition;
+  void set functionDefinition(Token functionDefinition2) {
+    this._functionDefinition = functionDefinition2;
   }
   /**
    * Set the semicolon terminating the statement to the given token.
    * @param semicolon the semicolon terminating the statement
    */
-  void set semicolon8(Token semicolon) {
-    this._semicolon = semicolon;
+  void set semicolon(Token semicolon8) {
+    this._semicolon = semicolon8;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_expression, visitor);
@@ -3638,10 +3988,16 @@
    * @param expression the expression that comprises the statement
    * @param semicolon the semicolon terminating the statement
    */
-  ExpressionStatement(Expression expression, Token semicolon) {
+  ExpressionStatement.full(Expression expression, Token semicolon) {
     this._expression = becomeParentOf(expression);
     this._semicolon = semicolon;
   }
+  /**
+   * Initialize a newly created expression statement.
+   * @param expression the expression that comprises the statement
+   * @param semicolon the semicolon terminating the statement
+   */
+  ExpressionStatement({Expression expression, Token semicolon}) : this.full(expression, semicolon);
   accept(ASTVisitor visitor) => visitor.visitExpressionStatement(this);
   Token get beginToken => _expression.beginToken;
   Token get endToken {
@@ -3665,15 +4021,15 @@
    * Set the expression that comprises the statement to the given expression.
    * @param expression the expression that comprises the statement
    */
-  void set expression5(Expression expression) {
-    this._expression = becomeParentOf(expression);
+  void set expression(Expression expression5) {
+    this._expression = becomeParentOf(expression5);
   }
   /**
    * Set the semicolon terminating the statement to the given token.
    * @param semicolon the semicolon terminating the statement
    */
-  void set semicolon9(Token semicolon) {
-    this._semicolon = semicolon;
+  void set semicolon(Token semicolon9) {
+    this._semicolon = semicolon9;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_expression, visitor);
@@ -3700,10 +4056,16 @@
    * @param keyword the token representing the 'extends' keyword
    * @param superclass the name of the class that is being extended
    */
-  ExtendsClause(Token keyword, TypeName superclass) {
+  ExtendsClause.full(Token keyword, TypeName superclass) {
     this._keyword = keyword;
     this._superclass = becomeParentOf(superclass);
   }
+  /**
+   * Initialize a newly created extends clause.
+   * @param keyword the token representing the 'extends' keyword
+   * @param superclass the name of the class that is being extended
+   */
+  ExtendsClause({Token keyword, TypeName superclass}) : this.full(keyword, superclass);
   accept(ASTVisitor visitor) => visitor.visitExtendsClause(this);
   Token get beginToken => _keyword;
   Token get endToken => _superclass.endToken;
@@ -3721,14 +4083,14 @@
    * Set the token representing the 'extends' keyword to the given token.
    * @param keyword the token representing the 'extends' keyword
    */
-  void set keyword8(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword8) {
+    this._keyword = keyword8;
   }
   /**
    * Set the name of the class that is being extended to the given name.
    * @param name the name of the class that is being extended
    */
-  void set superclass3(TypeName name) {
+  void set superclass(TypeName name) {
     _superclass = becomeParentOf(name);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -3764,11 +4126,20 @@
    * @param fieldList the fields being declared
    * @param semicolon the semicolon terminating the declaration
    */
-  FieldDeclaration(Comment comment, List<Annotation> metadata, Token keyword, VariableDeclarationList fieldList, Token semicolon) : super(comment, metadata) {
+  FieldDeclaration.full(Comment comment, List<Annotation> metadata, Token keyword, VariableDeclarationList fieldList, Token semicolon) : super.full(comment, metadata) {
     this._keyword = keyword;
     this._fieldList = becomeParentOf(fieldList);
     this._semicolon = semicolon;
   }
+  /**
+   * Initialize a newly created field declaration.
+   * @param comment the documentation comment associated with this field
+   * @param metadata the annotations associated with this field
+   * @param keyword the token representing the 'static' keyword
+   * @param fieldList the fields being declared
+   * @param semicolon the semicolon terminating the declaration
+   */
+  FieldDeclaration({Comment comment, List<Annotation> metadata, Token keyword, VariableDeclarationList fieldList, Token semicolon}) : this.full(comment, metadata, keyword, fieldList, semicolon);
   accept(ASTVisitor visitor) => visitor.visitFieldDeclaration(this);
   Token get endToken => _semicolon;
   /**
@@ -3791,22 +4162,22 @@
    * Set the fields being declared to the given list of variables.
    * @param fieldList the fields being declared
    */
-  void set fields2(VariableDeclarationList fieldList) {
+  void set fields(VariableDeclarationList fieldList) {
     fieldList = becomeParentOf(fieldList);
   }
   /**
    * Set the token representing the 'static' keyword to the given token.
    * @param keyword the token representing the 'static' keyword
    */
-  void set keyword9(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword9) {
+    this._keyword = keyword9;
   }
   /**
    * Set the semicolon terminating the declaration to the given token.
    * @param semicolon the semicolon terminating the declaration
    */
-  void set semicolon10(Token semicolon) {
-    this._semicolon = semicolon;
+  void set semicolon(Token semicolon10) {
+    this._semicolon = semicolon10;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     super.visitChildren(visitor);
@@ -3854,12 +4225,23 @@
    * @param period the token representing the period
    * @param identifier the name of the parameter being declared
    */
-  FieldFormalParameter(Comment comment, List<Annotation> metadata, Token keyword, TypeName type, Token thisToken, Token period, SimpleIdentifier identifier) : super(comment, metadata, identifier) {
+  FieldFormalParameter.full(Comment comment, List<Annotation> metadata, Token keyword, TypeName type, Token thisToken, Token period, SimpleIdentifier identifier) : super.full(comment, metadata, identifier) {
     this._keyword = keyword;
     this._type = becomeParentOf(type);
     this._thisToken = thisToken;
     this._period = period;
   }
+  /**
+   * Initialize a newly created formal parameter.
+   * @param comment the documentation comment associated with this parameter
+   * @param metadata the annotations associated with this parameter
+   * @param keyword the token representing either the 'final', 'const' or 'var' keyword
+   * @param type the name of the declared type of the parameter
+   * @param thisToken the token representing the 'this' keyword
+   * @param period the token representing the period
+   * @param identifier the name of the parameter being declared
+   */
+  FieldFormalParameter({Comment comment, List<Annotation> metadata, Token keyword, TypeName type, Token thisToken, Token period, SimpleIdentifier identifier}) : this.full(comment, metadata, keyword, type, thisToken, period, identifier);
   accept(ASTVisitor visitor) => visitor.visitFieldFormalParameter(this);
   Token get beginToken {
     if (_keyword != null) {
@@ -3891,34 +4273,34 @@
    * @return the name of the declared type of the parameter
    */
   TypeName get type => _type;
-  bool isConst() => (_keyword is KeywordToken) && (_keyword as KeywordToken).keyword == Keyword.CONST;
-  bool isFinal() => (_keyword is KeywordToken) && (_keyword as KeywordToken).keyword == Keyword.FINAL;
+  bool isConst() => (_keyword is KeywordToken) && identical(((_keyword as KeywordToken)).keyword, Keyword.CONST);
+  bool isFinal() => (_keyword is KeywordToken) && identical(((_keyword as KeywordToken)).keyword, Keyword.FINAL);
   /**
    * Set the token representing either the 'final', 'const' or 'var' keyword to the given token.
    * @param keyword the token representing either the 'final', 'const' or 'var' keyword
    */
-  void set keyword10(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword10) {
+    this._keyword = keyword10;
   }
   /**
    * Set the token representing the period to the given token.
    * @param period the token representing the period
    */
-  void set period6(Token period) {
-    this._period = period;
+  void set period(Token period6) {
+    this._period = period6;
   }
   /**
    * Set the token representing the 'this' keyword to the given token.
    * @param thisToken the token representing the 'this' keyword
    */
-  void set thisToken2(Token thisToken) {
-    this._thisToken = thisToken;
+  void set thisToken(Token thisToken2) {
+    this._thisToken = thisToken2;
   }
   /**
    * Set the name of the declared type of the parameter to the given type name.
    * @param typeName the name of the declared type of the parameter
    */
-  void set type4(TypeName typeName) {
+  void set type(TypeName typeName) {
     _type = becomeParentOf(typeName);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -3971,7 +4353,7 @@
    * @param rightParenthesis the right parenthesis
    * @param body the body of the loop
    */
-  ForEachStatement(Token forKeyword, Token leftParenthesis, SimpleFormalParameter loopParameter, Token inKeyword, Expression iterator, Token rightParenthesis, Statement body) {
+  ForEachStatement.full(Token forKeyword, Token leftParenthesis, SimpleFormalParameter loopParameter, Token inKeyword, Expression iterator, Token rightParenthesis, Statement body) {
     this._forKeyword = forKeyword;
     this._leftParenthesis = leftParenthesis;
     this._loopParameter = becomeParentOf(loopParameter);
@@ -3980,6 +4362,16 @@
     this._rightParenthesis = rightParenthesis;
     this._body = becomeParentOf(body);
   }
+  /**
+   * Initialize a newly created for-each statement.
+   * @param forKeyword the token representing the 'for' keyword
+   * @param leftParenthesis the left parenthesis
+   * @param loopParameter the declaration of the loop variable
+   * @param iterator the expression evaluated to produce the iterator
+   * @param rightParenthesis the right parenthesis
+   * @param body the body of the loop
+   */
+  ForEachStatement({Token forKeyword, Token leftParenthesis, SimpleFormalParameter loopParameter, Token inKeyword, Expression iterator, Token rightParenthesis, Statement body}) : this.full(forKeyword, leftParenthesis, loopParameter, inKeyword, iterator, rightParenthesis, body);
   accept(ASTVisitor visitor) => visitor.visitForEachStatement(this);
   Token get beginToken => _forKeyword;
   /**
@@ -4022,50 +4414,50 @@
    * Set the body of the loop to the given block.
    * @param body the body of the loop
    */
-  void set body5(Statement body) {
-    this._body = becomeParentOf(body);
+  void set body(Statement body2) {
+    this._body = becomeParentOf(body2);
   }
   /**
    * Set the token representing the 'for' keyword to the given token.
    * @param forKeyword the token representing the 'for' keyword
    */
-  void set forKeyword2(Token forKeyword) {
-    this._forKeyword = forKeyword;
+  void set forKeyword(Token forKeyword2) {
+    this._forKeyword = forKeyword2;
   }
   /**
    * Set the token representing the 'in' keyword to the given token.
    * @param inKeyword the token representing the 'in' keyword
    */
-  void set inKeyword2(Token inKeyword) {
-    this._inKeyword = inKeyword;
+  void set inKeyword(Token inKeyword2) {
+    this._inKeyword = inKeyword2;
   }
   /**
    * Set the expression evaluated to produce the iterator to the given expression.
    * @param expression the expression evaluated to produce the iterator
    */
-  void set iterator2(Expression expression) {
+  void set iterator(Expression expression) {
     _iterator = becomeParentOf(expression);
   }
   /**
    * Set the left parenthesis to the given token.
    * @param leftParenthesis the left parenthesis
    */
-  void set leftParenthesis6(Token leftParenthesis) {
-    this._leftParenthesis = leftParenthesis;
+  void set leftParenthesis(Token leftParenthesis3) {
+    this._leftParenthesis = leftParenthesis3;
   }
   /**
    * Set the declaration of the loop variable to the given parameter.
    * @param parameter the declaration of the loop variable
    */
-  void set loopParameter2(SimpleFormalParameter parameter) {
+  void set loopParameter(SimpleFormalParameter parameter) {
     _loopParameter = becomeParentOf(parameter);
   }
   /**
    * Set the right parenthesis to the given token.
    * @param rightParenthesis the right parenthesis
    */
-  void set rightParenthesis6(Token rightParenthesis) {
-    this._rightParenthesis = rightParenthesis;
+  void set rightParenthesis(Token rightParenthesis3) {
+    this._rightParenthesis = rightParenthesis3;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_loopParameter, visitor);
@@ -4140,7 +4532,7 @@
    * @param rightParenthesis the right parenthesis
    * @param body the body of the loop
    */
-  ForStatement(Token forKeyword, Token leftParenthesis, VariableDeclarationList variableList, Expression initialization, Token leftSeparator, Expression condition, Token rightSeparator, List<Expression> updaters, Token rightParenthesis, Statement body) {
+  ForStatement.full(Token forKeyword, Token leftParenthesis, VariableDeclarationList variableList, Expression initialization, Token leftSeparator, Expression condition, Token rightSeparator, List<Expression> updaters, Token rightParenthesis, Statement body) {
     this._updaters = new NodeList<Expression>(this);
     this._forKeyword = forKeyword;
     this._leftParenthesis = leftParenthesis;
@@ -4153,6 +4545,20 @@
     this._rightParenthesis = rightParenthesis;
     this._body = becomeParentOf(body);
   }
+  /**
+   * Initialize a newly created for statement.
+   * @param forKeyword the token representing the 'for' keyword
+   * @param leftParenthesis the left parenthesis
+   * @param variableList the declaration of the loop variables
+   * @param initialization the initialization expression
+   * @param leftSeparator the semicolon separating the initializer and the condition
+   * @param condition the condition used to determine when to terminate the loop
+   * @param rightSeparator the semicolon separating the condition and the updater
+   * @param updaters the list of expressions run after each execution of the loop body
+   * @param rightParenthesis the right parenthesis
+   * @param body the body of the loop
+   */
+  ForStatement({Token forKeyword, Token leftParenthesis, VariableDeclarationList variableList, Expression initialization, Token leftSeparator, Expression condition, Token rightSeparator, List<Expression> updaters, Token rightParenthesis, Statement body}) : this.full(forKeyword, leftParenthesis, variableList, initialization, leftSeparator, condition, rightSeparator, updaters, rightParenthesis, body);
   accept(ASTVisitor visitor) => visitor.visitForStatement(this);
   Token get beginToken => _forKeyword;
   /**
@@ -4210,63 +4616,63 @@
    * Set the body of the loop to the given statement.
    * @param body the body of the loop
    */
-  void set body6(Statement body) {
-    this._body = becomeParentOf(body);
+  void set body(Statement body3) {
+    this._body = becomeParentOf(body3);
   }
   /**
    * Set the condition used to determine when to terminate the loop to the given expression.
    * @param expression the condition used to determine when to terminate the loop
    */
-  void set condition5(Expression expression) {
+  void set condition(Expression expression) {
     _condition = becomeParentOf(expression);
   }
   /**
    * Set the token representing the 'for' keyword to the given token.
    * @param forKeyword the token representing the 'for' keyword
    */
-  void set forKeyword3(Token forKeyword) {
-    this._forKeyword = forKeyword;
+  void set forKeyword(Token forKeyword3) {
+    this._forKeyword = forKeyword3;
   }
   /**
    * Set the initialization expression to the given expression.
    * @param initialization the initialization expression
    */
-  void set initialization2(Expression initialization) {
-    this._initialization = becomeParentOf(initialization);
+  void set initialization(Expression initialization2) {
+    this._initialization = becomeParentOf(initialization2);
   }
   /**
    * Set the left parenthesis to the given token.
    * @param leftParenthesis the left parenthesis
    */
-  void set leftParenthesis7(Token leftParenthesis) {
-    this._leftParenthesis = leftParenthesis;
+  void set leftParenthesis(Token leftParenthesis4) {
+    this._leftParenthesis = leftParenthesis4;
   }
   /**
    * Set the semicolon separating the initializer and the condition to the given token.
    * @param leftSeparator the semicolon separating the initializer and the condition
    */
-  void set leftSeparator2(Token leftSeparator) {
-    this._leftSeparator = leftSeparator;
+  void set leftSeparator(Token leftSeparator2) {
+    this._leftSeparator = leftSeparator2;
   }
   /**
    * Set the right parenthesis to the given token.
    * @param rightParenthesis the right parenthesis
    */
-  void set rightParenthesis7(Token rightParenthesis) {
-    this._rightParenthesis = rightParenthesis;
+  void set rightParenthesis(Token rightParenthesis4) {
+    this._rightParenthesis = rightParenthesis4;
   }
   /**
    * Set the semicolon separating the condition and the updater to the given token.
    * @param rightSeparator the semicolon separating the condition and the updater
    */
-  void set rightSeparator2(Token rightSeparator) {
-    this._rightSeparator = rightSeparator;
+  void set rightSeparator(Token rightSeparator2) {
+    this._rightSeparator = rightSeparator2;
   }
   /**
    * Set the declaration of the loop variables to the given parameter.
    * @param variableList the declaration of the loop variables
    */
-  void set variables2(VariableDeclarationList variableList) {
+  void set variables(VariableDeclarationList variableList) {
     variableList = becomeParentOf(variableList);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -4290,11 +4696,11 @@
    * @return the element representing this parameter
    */
   ParameterElement get element {
-    SimpleIdentifier identifier6 = identifier;
-    if (identifier6 == null) {
+    SimpleIdentifier identifier9 = identifier;
+    if (identifier9 == null) {
       return null;
     }
-    return identifier6.element as ParameterElement;
+    return (identifier9.element as ParameterElement);
   }
   /**
    * Return the name of the parameter being declared.
@@ -4359,7 +4765,7 @@
    * @param rightDelimiter the right delimiter introducing the optional parameters
    * @param rightParenthesis the right parenthesis
    */
-  FormalParameterList(Token leftParenthesis, List<FormalParameter> parameters, Token leftDelimiter, Token rightDelimiter, Token rightParenthesis) {
+  FormalParameterList.full(Token leftParenthesis, List<FormalParameter> parameters, Token leftDelimiter, Token rightDelimiter, Token rightParenthesis) {
     this._parameters = new NodeList<FormalParameter>(this);
     this._leftParenthesis = leftParenthesis;
     this._parameters.addAll(parameters);
@@ -4367,6 +4773,15 @@
     this._rightDelimiter = rightDelimiter;
     this._rightParenthesis = rightParenthesis;
   }
+  /**
+   * Initialize a newly created parameter list.
+   * @param leftParenthesis the left parenthesis
+   * @param parameters the parameters associated with the method
+   * @param leftDelimiter the left delimiter introducing the optional parameters
+   * @param rightDelimiter the right delimiter introducing the optional parameters
+   * @param rightParenthesis the right parenthesis
+   */
+  FormalParameterList({Token leftParenthesis, List<FormalParameter> parameters, Token leftDelimiter, Token rightDelimiter, Token rightParenthesis}) : this.full(leftParenthesis, parameters, leftDelimiter, rightDelimiter, rightParenthesis);
   accept(ASTVisitor visitor) => visitor.visitFormalParameterList(this);
   Token get beginToken => _leftParenthesis;
   /**
@@ -4417,14 +4832,14 @@
    * to the given token.
    * @param bracket the left delimiter introducing the optional parameters
    */
-  void set leftDelimiter2(Token bracket) {
+  void set leftDelimiter(Token bracket) {
     _leftDelimiter = bracket;
   }
   /**
    * Set the left parenthesis to the given token.
    * @param parenthesis the left parenthesis
    */
-  void set leftParenthesis8(Token parenthesis) {
+  void set leftParenthesis(Token parenthesis) {
     _leftParenthesis = parenthesis;
   }
   /**
@@ -4432,14 +4847,14 @@
    * parameters to the given token.
    * @param bracket the right delimiter introducing the optional parameters
    */
-  void set rightDelimiter2(Token bracket) {
+  void set rightDelimiter(Token bracket) {
     _rightDelimiter = bracket;
   }
   /**
    * Set the right parenthesis to the given token.
    * @param parenthesis the right parenthesis
    */
-  void set rightParenthesis8(Token parenthesis) {
+  void set rightParenthesis(Token parenthesis) {
     _rightParenthesis = parenthesis;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -4495,20 +4910,31 @@
    * @param name the name of the function
    * @param functionExpression the function expression being wrapped
    */
-  FunctionDeclaration(Comment comment, List<Annotation> metadata, Token externalKeyword, TypeName returnType, Token propertyKeyword, SimpleIdentifier name, FunctionExpression functionExpression) : super(comment, metadata) {
+  FunctionDeclaration.full(Comment comment, List<Annotation> metadata, Token externalKeyword, TypeName returnType, Token propertyKeyword, SimpleIdentifier name, FunctionExpression functionExpression) : super.full(comment, metadata) {
     this._externalKeyword = externalKeyword;
     this._returnType = becomeParentOf(returnType);
     this._propertyKeyword = propertyKeyword;
     this._name = becomeParentOf(name);
     this._functionExpression = becomeParentOf(functionExpression);
   }
+  /**
+   * Initialize a newly created function declaration.
+   * @param comment the documentation comment associated with this function
+   * @param metadata the annotations associated with this function
+   * @param externalKeyword the token representing the 'external' keyword
+   * @param returnType the return type of the function
+   * @param propertyKeyword the token representing the 'get' or 'set' keyword
+   * @param name the name of the function
+   * @param functionExpression the function expression being wrapped
+   */
+  FunctionDeclaration({Comment comment, List<Annotation> metadata, Token externalKeyword, TypeName returnType, Token propertyKeyword, SimpleIdentifier name, FunctionExpression functionExpression}) : this.full(comment, metadata, externalKeyword, returnType, propertyKeyword, name, functionExpression);
   accept(ASTVisitor visitor) => visitor.visitFunctionDeclaration(this);
   /**
    * Return the {@link FunctionElement} associated with this function, or {@code null} if the AST
    * structure has not been resolved.
    * @return the {@link FunctionElement} associated with this function
    */
-  FunctionElement get element => _name != null ? _name.element as FunctionElement : null;
+  FunctionElement get element => _name != null ? (_name.element as FunctionElement) : null;
   Token get endToken => _functionExpression.endToken;
   /**
    * Return the token representing the 'external' keyword, or {@code null} if this is not an
@@ -4541,35 +4967,35 @@
    * Set the token representing the 'external' keyword to the given token.
    * @param externalKeyword the token representing the 'external' keyword
    */
-  void set externalKeyword3(Token externalKeyword) {
-    this._externalKeyword = externalKeyword;
+  void set externalKeyword(Token externalKeyword3) {
+    this._externalKeyword = externalKeyword3;
   }
   /**
    * Set the function expression being wrapped to the given function expression.
    * @param functionExpression the function expression being wrapped
    */
-  void set functionExpression2(FunctionExpression functionExpression) {
-    functionExpression = becomeParentOf(functionExpression);
+  void set functionExpression(FunctionExpression functionExpression3) {
+    functionExpression3 = becomeParentOf(functionExpression3);
   }
   /**
    * Set the name of the function to the given identifier.
    * @param identifier the name of the function
    */
-  void set name7(SimpleIdentifier identifier) {
+  void set name(SimpleIdentifier identifier) {
     _name = becomeParentOf(identifier);
   }
   /**
    * Set the token representing the 'get' or 'set' keyword to the given token.
    * @param propertyKeyword the token representing the 'get' or 'set' keyword
    */
-  void set propertyKeyword2(Token propertyKeyword) {
-    this._propertyKeyword = propertyKeyword;
+  void set propertyKeyword(Token propertyKeyword2) {
+    this._propertyKeyword = propertyKeyword2;
   }
   /**
    * Set the return type of the function to the given name.
    * @param name the return type of the function
    */
-  void set returnType3(TypeName name) {
+  void set returnType(TypeName name) {
     _returnType = becomeParentOf(name);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -4604,9 +5030,14 @@
    * Initialize a newly created function declaration statement.
    * @param functionDeclaration the the function declaration being wrapped
    */
-  FunctionDeclarationStatement(FunctionDeclaration functionDeclaration) {
+  FunctionDeclarationStatement.full(FunctionDeclaration functionDeclaration) {
     this._functionDeclaration = becomeParentOf(functionDeclaration);
   }
+  /**
+   * Initialize a newly created function declaration statement.
+   * @param functionDeclaration the the function declaration being wrapped
+   */
+  FunctionDeclarationStatement({FunctionDeclaration functionDeclaration}) : this.full(functionDeclaration);
   accept(ASTVisitor visitor) => visitor.visitFunctionDeclarationStatement(this);
   Token get beginToken => _functionDeclaration.beginToken;
   Token get endToken => _functionDeclaration.endToken;
@@ -4619,8 +5050,8 @@
    * Set the function declaration being wrapped to the given function declaration.
    * @param functionDeclaration the function declaration being wrapped
    */
-  void set functionExpression(FunctionDeclaration functionDeclaration) {
-    this._functionDeclaration = becomeParentOf(functionDeclaration);
+  void set functionExpression(FunctionDeclaration functionDeclaration2) {
+    this._functionDeclaration = becomeParentOf(functionDeclaration2);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_functionDeclaration, visitor);
@@ -4650,10 +5081,16 @@
    * @param parameters the parameters associated with the function
    * @param body the body of the function
    */
-  FunctionExpression(FormalParameterList parameters, FunctionBody body) {
+  FunctionExpression.full(FormalParameterList parameters, FunctionBody body) {
     this._parameters = becomeParentOf(parameters);
     this._body = becomeParentOf(body);
   }
+  /**
+   * Initialize a newly created function declaration.
+   * @param parameters the parameters associated with the function
+   * @param body the body of the function
+   */
+  FunctionExpression({FormalParameterList parameters, FunctionBody body}) : this.full(parameters, body);
   accept(ASTVisitor visitor) => visitor.visitFunctionExpression(this);
   Token get beginToken {
     if (_parameters != null) {
@@ -4691,22 +5128,22 @@
    * Set the body of the function to the given function body.
    * @param functionBody the body of the function
    */
-  void set body7(FunctionBody functionBody) {
+  void set body(FunctionBody functionBody) {
     _body = becomeParentOf(functionBody);
   }
   /**
    * Set the element associated with this function to the given element.
    * @param element the element associated with this function
    */
-  void set element8(ExecutableElement element) {
-    this._element = element;
+  void set element(ExecutableElement element9) {
+    this._element = element9;
   }
   /**
    * Set the parameters associated with the function to the given list of parameters.
    * @param parameters the parameters associated with the function
    */
-  void set parameters3(FormalParameterList parameters) {
-    this._parameters = becomeParentOf(parameters);
+  void set parameters(FormalParameterList parameters3) {
+    this._parameters = becomeParentOf(parameters3);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_parameters, visitor);
@@ -4740,10 +5177,16 @@
    * @param function the expression producing the function being invoked
    * @param argumentList the list of arguments to the method
    */
-  FunctionExpressionInvocation(Expression function, ArgumentList argumentList) {
+  FunctionExpressionInvocation.full(Expression function, ArgumentList argumentList) {
     this._function = becomeParentOf(function);
     this._argumentList = becomeParentOf(argumentList);
   }
+  /**
+   * Initialize a newly created function expression invocation.
+   * @param function the expression producing the function being invoked
+   * @param argumentList the list of arguments to the method
+   */
+  FunctionExpressionInvocation({Expression function, ArgumentList argumentList}) : this.full(function, argumentList);
   accept(ASTVisitor visitor) => visitor.visitFunctionExpressionInvocation(this);
   /**
    * Return the list of arguments to the method.
@@ -4768,22 +5211,22 @@
    * Set the list of arguments to the method to the given list.
    * @param argumentList the list of arguments to the method
    */
-  void set argumentList5(ArgumentList argumentList) {
-    this._argumentList = becomeParentOf(argumentList);
+  void set argumentList(ArgumentList argumentList5) {
+    this._argumentList = becomeParentOf(argumentList5);
   }
   /**
    * Set the element associated with the function being invoked to the given element.
    * @param element the element associated with the function being invoked
    */
-  void set element9(ExecutableElement element) {
-    this._element = element;
+  void set element(ExecutableElement element10) {
+    this._element = element10;
   }
   /**
    * Set the expression producing the function being invoked to the given expression.
    * @param function the expression producing the function being invoked
    */
-  void set function2(Expression function) {
-    function = becomeParentOf(function);
+  void set function(Expression function2) {
+    function2 = becomeParentOf(function2);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_function, visitor);
@@ -4827,19 +5270,31 @@
    * @param parameters the parameters associated with the function
    * @param semicolon the semicolon terminating the declaration
    */
-  FunctionTypeAlias(Comment comment, List<Annotation> metadata, Token keyword, TypeName returnType, SimpleIdentifier name, TypeParameterList typeParameters, FormalParameterList parameters, Token semicolon) : super(comment, metadata, keyword, semicolon) {
+  FunctionTypeAlias.full(Comment comment, List<Annotation> metadata, Token keyword, TypeName returnType, SimpleIdentifier name, TypeParameterList typeParameters, FormalParameterList parameters, Token semicolon) : super.full(comment, metadata, keyword, semicolon) {
     this._returnType = becomeParentOf(returnType);
     this._name = becomeParentOf(name);
     this._typeParameters = becomeParentOf(typeParameters);
     this._parameters = becomeParentOf(parameters);
   }
+  /**
+   * Initialize a newly created function type alias.
+   * @param comment the documentation comment associated with this type alias
+   * @param metadata the annotations associated with this type alias
+   * @param keyword the token representing the 'typedef' keyword
+   * @param returnType the name of the return type of the function type being defined
+   * @param name the name of the type being declared
+   * @param typeParameters the type parameters for the type
+   * @param parameters the parameters associated with the function
+   * @param semicolon the semicolon terminating the declaration
+   */
+  FunctionTypeAlias({Comment comment, List<Annotation> metadata, Token keyword, TypeName returnType, SimpleIdentifier name, TypeParameterList typeParameters, FormalParameterList parameters, Token semicolon}) : this.full(comment, metadata, keyword, returnType, name, typeParameters, parameters, semicolon);
   accept(ASTVisitor visitor) => visitor.visitFunctionTypeAlias(this);
   /**
    * Return the {@link TypeAliasElement} associated with this type alias, or {@code null} if the AST
    * structure has not been resolved.
    * @return the {@link TypeAliasElement} associated with this type alias
    */
-  TypeAliasElement get element => _name != null ? _name.element as TypeAliasElement : null;
+  TypeAliasElement get element => _name != null ? (_name.element as TypeAliasElement) : null;
   /**
    * Return the name of the function type being declared.
    * @return the name of the function type being declared
@@ -4866,29 +5321,29 @@
    * Set the name of the function type being declared to the given identifier.
    * @param name the name of the function type being declared
    */
-  void set name8(SimpleIdentifier name) {
-    this._name = becomeParentOf(name);
+  void set name(SimpleIdentifier name5) {
+    this._name = becomeParentOf(name5);
   }
   /**
    * Set the parameters associated with the function type to the given list of parameters.
    * @param parameters the parameters associated with the function type
    */
-  void set parameters4(FormalParameterList parameters) {
-    this._parameters = becomeParentOf(parameters);
+  void set parameters(FormalParameterList parameters4) {
+    this._parameters = becomeParentOf(parameters4);
   }
   /**
    * Set the name of the return type of the function type being defined to the given type name.
    * @param typeName the name of the return type of the function type being defined
    */
-  void set returnType4(TypeName typeName) {
+  void set returnType(TypeName typeName) {
     _returnType = becomeParentOf(typeName);
   }
   /**
    * Set the type parameters for the function type to the given list of parameters.
    * @param typeParameters the type parameters for the function type
    */
-  void set typeParameters4(TypeParameterList typeParameters) {
-    this._typeParameters = becomeParentOf(typeParameters);
+  void set typeParameters(TypeParameterList typeParameters4) {
+    this._typeParameters = becomeParentOf(typeParameters4);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     super.visitChildren(visitor);
@@ -4922,10 +5377,20 @@
    * @param identifier the name of the function-typed parameter
    * @param parameters the parameters of the function-typed parameter
    */
-  FunctionTypedFormalParameter(Comment comment, List<Annotation> metadata, TypeName returnType, SimpleIdentifier identifier, FormalParameterList parameters) : super(comment, metadata, identifier) {
+  FunctionTypedFormalParameter.full(Comment comment, List<Annotation> metadata, TypeName returnType, SimpleIdentifier identifier, FormalParameterList parameters) : super.full(comment, metadata, identifier) {
     this._returnType = becomeParentOf(returnType);
     this._parameters = becomeParentOf(parameters);
   }
+  /**
+   * Initialize a newly created formal parameter.
+   * @param comment the documentation comment associated with this parameter
+   * @param metadata the annotations associated with this parameter
+   * @param returnType the return type of the function, or {@code null} if the function does not
+   * have a return type
+   * @param identifier the name of the function-typed parameter
+   * @param parameters the parameters of the function-typed parameter
+   */
+  FunctionTypedFormalParameter({Comment comment, List<Annotation> metadata, TypeName returnType, SimpleIdentifier identifier, FormalParameterList parameters}) : this.full(comment, metadata, returnType, identifier, parameters);
   accept(ASTVisitor visitor) => visitor.visitFunctionTypedFormalParameter(this);
   Token get beginToken {
     if (_returnType != null) {
@@ -4951,15 +5416,15 @@
    * Set the parameters of the function-typed parameter to the given parameters.
    * @param parameters the parameters of the function-typed parameter
    */
-  void set parameters5(FormalParameterList parameters) {
-    this._parameters = becomeParentOf(parameters);
+  void set parameters(FormalParameterList parameters5) {
+    this._parameters = becomeParentOf(parameters5);
   }
   /**
    * Set the return type of the function to the given type.
    * @param returnType the return type of the function
    */
-  void set returnType5(TypeName returnType) {
-    this._returnType = becomeParentOf(returnType);
+  void set returnType(TypeName returnType2) {
+    this._returnType = becomeParentOf(returnType2);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     super.visitChildren(visitor);
@@ -4986,10 +5451,16 @@
    * @param keyword the comma introducing the combinator
    * @param hiddenNames the list of names from the library that are hidden by this combinator
    */
-  HideCombinator(Token keyword, List<SimpleIdentifier> hiddenNames) : super(keyword) {
+  HideCombinator.full(Token keyword, List<SimpleIdentifier> hiddenNames) : super.full(keyword) {
     this._hiddenNames = new NodeList<SimpleIdentifier>(this);
     this._hiddenNames.addAll(hiddenNames);
   }
+  /**
+   * Initialize a newly created import show combinator.
+   * @param keyword the comma introducing the combinator
+   * @param hiddenNames the list of names from the library that are hidden by this combinator
+   */
+  HideCombinator({Token keyword, List<SimpleIdentifier> hiddenNames}) : this.full(keyword, hiddenNames);
   accept(ASTVisitor visitor) => visitor.visitHideCombinator(this);
   Token get endToken => _hiddenNames.endToken;
   /**
@@ -5037,8 +5508,8 @@
    * Set the element associated with this identifier to the given element.
    * @param element the element associated with this identifier
    */
-  void set element10(Element element) {
-    this._element = element;
+  void set element(Element element11) {
+    this._element = element11;
   }
 }
 /**
@@ -5088,7 +5559,7 @@
    * @param elseKeyword the token representing the 'else' keyword
    * @param elseStatement the statement that is executed if the condition evaluates to {@code false}
    */
-  IfStatement(Token ifKeyword, Token leftParenthesis, Expression condition, Token rightParenthesis, Statement thenStatement, Token elseKeyword, Statement elseStatement) {
+  IfStatement.full(Token ifKeyword, Token leftParenthesis, Expression condition, Token rightParenthesis, Statement thenStatement, Token elseKeyword, Statement elseStatement) {
     this._ifKeyword = ifKeyword;
     this._leftParenthesis = leftParenthesis;
     this._condition = becomeParentOf(condition);
@@ -5097,6 +5568,17 @@
     this._elseKeyword = elseKeyword;
     this._elseStatement = becomeParentOf(elseStatement);
   }
+  /**
+   * Initialize a newly created if statement.
+   * @param ifKeyword the token representing the 'if' keyword
+   * @param leftParenthesis the left parenthesis
+   * @param condition the condition used to determine which of the statements is executed next
+   * @param rightParenthesis the right parenthesis
+   * @param thenStatement the statement that is executed if the condition evaluates to {@code true}
+   * @param elseKeyword the token representing the 'else' keyword
+   * @param elseStatement the statement that is executed if the condition evaluates to {@code false}
+   */
+  IfStatement({Token ifKeyword, Token leftParenthesis, Expression condition, Token rightParenthesis, Statement thenStatement, Token elseKeyword, Statement elseStatement}) : this.full(ifKeyword, leftParenthesis, condition, rightParenthesis, thenStatement, elseKeyword, elseStatement);
   accept(ASTVisitor visitor) => visitor.visitIfStatement(this);
   Token get beginToken => _ifKeyword;
   /**
@@ -5145,51 +5627,51 @@
    * expression.
    * @param expression the condition used to determine which statement is executed next
    */
-  void set condition6(Expression expression) {
+  void set condition(Expression expression) {
     _condition = becomeParentOf(expression);
   }
   /**
    * Set the token representing the 'else' keyword to the given token.
    * @param elseKeyword the token representing the 'else' keyword
    */
-  void set elseKeyword2(Token elseKeyword) {
-    this._elseKeyword = elseKeyword;
+  void set elseKeyword(Token elseKeyword2) {
+    this._elseKeyword = elseKeyword2;
   }
   /**
    * Set the statement that is executed if the condition evaluates to {@code false} to the given
    * statement.
    * @param statement the statement that is executed if the condition evaluates to {@code false}
    */
-  void set elseStatement2(Statement statement) {
+  void set elseStatement(Statement statement) {
     _elseStatement = becomeParentOf(statement);
   }
   /**
    * Set the token representing the 'if' keyword to the given token.
    * @param ifKeyword the token representing the 'if' keyword
    */
-  void set ifKeyword2(Token ifKeyword) {
-    this._ifKeyword = ifKeyword;
+  void set ifKeyword(Token ifKeyword2) {
+    this._ifKeyword = ifKeyword2;
   }
   /**
    * Set the left parenthesis to the given token.
    * @param leftParenthesis the left parenthesis
    */
-  void set leftParenthesis9(Token leftParenthesis) {
-    this._leftParenthesis = leftParenthesis;
+  void set leftParenthesis(Token leftParenthesis5) {
+    this._leftParenthesis = leftParenthesis5;
   }
   /**
    * Set the right parenthesis to the given token.
    * @param rightParenthesis the right parenthesis
    */
-  void set rightParenthesis9(Token rightParenthesis) {
-    this._rightParenthesis = rightParenthesis;
+  void set rightParenthesis(Token rightParenthesis5) {
+    this._rightParenthesis = rightParenthesis5;
   }
   /**
    * Set the statement that is executed if the condition evaluates to {@code true} to the given
    * statement.
    * @param statement the statement that is executed if the condition evaluates to {@code true}
    */
-  void set thenStatement2(Statement statement) {
+  void set thenStatement(Statement statement) {
     _thenStatement = becomeParentOf(statement);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -5220,11 +5702,17 @@
    * @param keyword the token representing the 'implements' keyword
    * @param interfaces the interfaces that are being implemented
    */
-  ImplementsClause(Token keyword, List<TypeName> interfaces) {
+  ImplementsClause.full(Token keyword, List<TypeName> interfaces) {
     this._interfaces = new NodeList<TypeName>(this);
     this._keyword = keyword;
     this._interfaces.addAll(interfaces);
   }
+  /**
+   * Initialize a newly created extends clause.
+   * @param keyword the token representing the 'implements' keyword
+   * @param interfaces the interfaces that are being implemented
+   */
+  ImplementsClause({Token keyword, List<TypeName> interfaces}) : this.full(keyword, interfaces);
   accept(ASTVisitor visitor) => visitor.visitImplementsClause(this);
   Token get beginToken => _keyword;
   Token get endToken => _interfaces.endToken;
@@ -5242,8 +5730,8 @@
    * Set the token representing the 'implements' keyword to the given token.
    * @param keyword the token representing the 'implements' keyword
    */
-  void set keyword11(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword11) {
+    this._keyword = keyword11;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     _interfaces.accept(visitor);
@@ -5276,10 +5764,22 @@
    * @param combinators the combinators used to control how names are imported
    * @param semicolon the semicolon terminating the directive
    */
-  ImportDirective(Comment comment, List<Annotation> metadata, Token keyword, StringLiteral libraryUri, Token asToken, SimpleIdentifier prefix, List<Combinator> combinators, Token semicolon) : super(comment, metadata, keyword, libraryUri, combinators, semicolon) {
+  ImportDirective.full(Comment comment, List<Annotation> metadata, Token keyword, StringLiteral libraryUri, Token asToken, SimpleIdentifier prefix, List<Combinator> combinators, Token semicolon) : super.full(comment, metadata, keyword, libraryUri, combinators, semicolon) {
     this._asToken = asToken;
     this._prefix = becomeParentOf(prefix);
   }
+  /**
+   * Initialize a newly created import directive.
+   * @param comment the documentation comment associated with this directive
+   * @param metadata the annotations associated with the directive
+   * @param keyword the token representing the 'import' keyword
+   * @param libraryUri the URI of the library being imported
+   * @param asToken the token representing the 'as' token
+   * @param prefix the prefix to be used with the imported names
+   * @param combinators the combinators used to control how names are imported
+   * @param semicolon the semicolon terminating the directive
+   */
+  ImportDirective({Comment comment, List<Annotation> metadata, Token keyword, StringLiteral libraryUri, Token asToken, SimpleIdentifier prefix, List<Combinator> combinators, Token semicolon}) : this.full(comment, metadata, keyword, libraryUri, asToken, prefix, combinators, semicolon);
   accept(ASTVisitor visitor) => visitor.visitImportDirective(this);
   /**
    * Return the token representing the 'as' token, or {@code null} if the imported names are not
@@ -5297,19 +5797,18 @@
    * Set the token representing the 'as' token to the given token.
    * @param asToken the token representing the 'as' token
    */
-  void set asToken2(Token asToken) {
-    this._asToken = asToken;
+  void set asToken(Token asToken2) {
+    this._asToken = asToken2;
   }
   /**
    * Set the prefix to be used with the imported names to the given identifier.
    * @param prefix the prefix to be used with the imported names
    */
-  void set prefix2(SimpleIdentifier prefix) {
-    this._prefix = becomeParentOf(prefix);
+  void set prefix(SimpleIdentifier prefix2) {
+    this._prefix = becomeParentOf(prefix2);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     super.visitChildren(visitor);
-    safelyVisitChild(libraryUri, visitor);
     safelyVisitChild(_prefix, visitor);
     combinators.accept(visitor);
   }
@@ -5355,14 +5854,22 @@
    * @param index the expression used to compute the index
    * @param rightBracket the right square bracket
    */
-  IndexExpression.con1(Expression target, Token leftBracket, Expression index, Token rightBracket) {
-    _jtd_constructor_55_impl(target, leftBracket, index, rightBracket);
+  IndexExpression.forTarget_full(Expression target3, Token leftBracket4, Expression index2, Token rightBracket4) {
+    _jtd_constructor_56_impl(target3, leftBracket4, index2, rightBracket4);
   }
-  _jtd_constructor_55_impl(Expression target, Token leftBracket, Expression index, Token rightBracket) {
-    this._target = becomeParentOf(target);
-    this._leftBracket = leftBracket;
-    this._index = becomeParentOf(index);
-    this._rightBracket = rightBracket;
+  /**
+   * Initialize a newly created index expression.
+   * @param target the expression used to compute the object being indexed
+   * @param leftBracket the left square bracket
+   * @param index the expression used to compute the index
+   * @param rightBracket the right square bracket
+   */
+  IndexExpression.forTarget({Expression target3, Token leftBracket4, Expression index2, Token rightBracket4}) : this.forTarget_full(target3, leftBracket4, index2, rightBracket4);
+  _jtd_constructor_56_impl(Expression target3, Token leftBracket4, Expression index2, Token rightBracket4) {
+    this._target = becomeParentOf(target3);
+    this._leftBracket = leftBracket4;
+    this._index = becomeParentOf(index2);
+    this._rightBracket = rightBracket4;
   }
   /**
    * Initialize a newly created index expression.
@@ -5371,14 +5878,22 @@
    * @param index the expression used to compute the index
    * @param rightBracket the right square bracket
    */
-  IndexExpression.con2(Token period, Token leftBracket, Expression index, Token rightBracket) {
-    _jtd_constructor_56_impl(period, leftBracket, index, rightBracket);
+  IndexExpression.forCascade_full(Token period7, Token leftBracket5, Expression index3, Token rightBracket5) {
+    _jtd_constructor_57_impl(period7, leftBracket5, index3, rightBracket5);
   }
-  _jtd_constructor_56_impl(Token period, Token leftBracket, Expression index, Token rightBracket) {
-    this._period = period;
-    this._leftBracket = leftBracket;
-    this._index = becomeParentOf(index);
-    this._rightBracket = rightBracket;
+  /**
+   * Initialize a newly created index expression.
+   * @param period the period ("..") before a cascaded index expression
+   * @param leftBracket the left square bracket
+   * @param index the expression used to compute the index
+   * @param rightBracket the right square bracket
+   */
+  IndexExpression.forCascade({Token period7, Token leftBracket5, Expression index3, Token rightBracket5}) : this.forCascade_full(period7, leftBracket5, index3, rightBracket5);
+  _jtd_constructor_57_impl(Token period7, Token leftBracket5, Expression index3, Token rightBracket5) {
+    this._period = period7;
+    this._leftBracket = leftBracket5;
+    this._index = becomeParentOf(index3);
+    this._rightBracket = rightBracket5;
   }
   accept(ASTVisitor visitor) => visitor.visitIndexExpression(this);
   /**
@@ -5435,7 +5950,7 @@
         }
         ancestor = ancestor.parent;
       }
-      return (ancestor as CascadeExpression).target;
+      return ((ancestor as CascadeExpression)).target;
     }
     return _target;
   }
@@ -5452,10 +5967,10 @@
    * @return {@code true} if this expression is in a context where the operator '[]' will be invoked
    */
   bool inGetterContext() {
-    ASTNode parent4 = parent;
-    if (parent4 is AssignmentExpression) {
-      AssignmentExpression assignment = parent4 as AssignmentExpression;
-      if (assignment.leftHandSide == this && assignment.operator.type == TokenType.EQ) {
+    ASTNode parent3 = parent;
+    if (parent3 is AssignmentExpression) {
+      AssignmentExpression assignment = (parent3 as AssignmentExpression);
+      if (identical(assignment.leftHandSide, this) && identical(assignment.operator.type, TokenType.EQ)) {
         return false;
       }
     }
@@ -5470,13 +5985,13 @@
    * invoked
    */
   bool inSetterContext() {
-    ASTNode parent5 = parent;
-    if (parent5 is PrefixExpression) {
-      return (parent5 as PrefixExpression).operator.type.isIncrementOperator();
-    } else if (parent5 is PostfixExpression) {
+    ASTNode parent4 = parent;
+    if (parent4 is PrefixExpression) {
+      return ((parent4 as PrefixExpression)).operator.type.isIncrementOperator();
+    } else if (parent4 is PostfixExpression) {
       return true;
-    } else if (parent5 is AssignmentExpression) {
-      return (parent5 as AssignmentExpression).leftHandSide == this;
+    } else if (parent4 is AssignmentExpression) {
+      return identical(((parent4 as AssignmentExpression)).leftHandSide, this);
     }
     return false;
   }
@@ -5491,42 +6006,42 @@
    * Set the expression used to compute the object being indexed to the given expression.
    * @param expression the expression used to compute the object being indexed
    */
-  void set array2(Expression expression) {
+  void set array(Expression expression) {
     _target = becomeParentOf(expression);
   }
   /**
    * Set the element associated with the operator to the given element.
    * @param element the element associated with this operator
    */
-  void set element11(MethodElement element) {
-    this._element = element;
+  void set element(MethodElement element12) {
+    this._element = element12;
   }
   /**
    * Set the expression used to compute the index to the given expression.
    * @param expression the expression used to compute the index
    */
-  void set index2(Expression expression) {
+  void set index(Expression expression) {
     _index = becomeParentOf(expression);
   }
   /**
    * Set the left square bracket to the given token.
    * @param bracket the left square bracket
    */
-  void set leftBracket4(Token bracket) {
+  void set leftBracket(Token bracket) {
     _leftBracket = bracket;
   }
   /**
    * Set the period ("..") before a cascaded index expression to the given token.
    * @param period the period ("..") before a cascaded index expression
    */
-  void set period7(Token period) {
-    this._period = period;
+  void set period(Token period8) {
+    this._period = period8;
   }
   /**
    * Set the right square bracket to the given token.
    * @param bracket the right square bracket
    */
-  void set rightBracket4(Token bracket) {
+  void set rightBracket(Token bracket) {
     _rightBracket = bracket;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -5565,11 +6080,18 @@
    * @param constructorName the name of the constructor to be invoked
    * @param argumentList the list of arguments to the constructor
    */
-  InstanceCreationExpression(Token keyword, ConstructorName constructorName, ArgumentList argumentList) {
+  InstanceCreationExpression.full(Token keyword, ConstructorName constructorName, ArgumentList argumentList) {
     this._keyword = keyword;
     this._constructorName = becomeParentOf(constructorName);
     this._argumentList = becomeParentOf(argumentList);
   }
+  /**
+   * Initialize a newly created instance creation expression.
+   * @param keyword the keyword used to indicate how an object should be created
+   * @param constructorName the name of the constructor to be invoked
+   * @param argumentList the list of arguments to the constructor
+   */
+  InstanceCreationExpression({Token keyword, ConstructorName constructorName, ArgumentList argumentList}) : this.full(keyword, constructorName, argumentList);
   accept(ASTVisitor visitor) => visitor.visitInstanceCreationExpression(this);
   /**
    * Return the list of arguments to the constructor.
@@ -5598,29 +6120,29 @@
    * Set the list of arguments to the constructor to the given list.
    * @param argumentList the list of arguments to the constructor
    */
-  void set argumentList6(ArgumentList argumentList) {
-    this._argumentList = becomeParentOf(argumentList);
+  void set argumentList(ArgumentList argumentList6) {
+    this._argumentList = becomeParentOf(argumentList6);
   }
   /**
    * Set the name of the constructor to be invoked to the given name.
    * @param constructorName the name of the constructor to be invoked
    */
-  void set constructorName3(ConstructorName constructorName) {
-    this._constructorName = constructorName;
+  void set constructorName(ConstructorName constructorName3) {
+    this._constructorName = constructorName3;
   }
   /**
    * Set the element associated with the constructor to the given element.
    * @param element the element associated with the constructor
    */
-  void set element12(ConstructorElement element) {
-    this._element = element;
+  void set element(ConstructorElement element13) {
+    this._element = element13;
   }
   /**
    * Set the keyword used to indicate how an object should be created to the given keyword.
    * @param keyword the keyword used to indicate how an object should be created
    */
-  void set keyword12(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword12) {
+    this._keyword = keyword12;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_constructorName, visitor);
@@ -5654,24 +6176,16 @@
    * @param literal the token representing the literal
    * @param value the value of the literal
    */
-  IntegerLiteral.con1(Token literal, int value) {
-    _jtd_constructor_58_impl(literal, value);
-  }
-  _jtd_constructor_58_impl(Token literal, int value) {
+  IntegerLiteral.full(Token literal, int value) {
     this._literal = literal;
     this._value = value;
   }
   /**
    * Initialize a newly created integer literal.
-   * @param token the token representing the literal
+   * @param literal the token representing the literal
    * @param value the value of the literal
    */
-  IntegerLiteral.con2(Token token, int value) {
-    _jtd_constructor_59_impl(token, value);
-  }
-  _jtd_constructor_59_impl(Token token, int value) {
-    _jtd_constructor_58_impl(token, value);
-  }
+  IntegerLiteral({Token literal, int value}) : this.full(literal, value);
   accept(ASTVisitor visitor) => visitor.visitIntegerLiteral(this);
   Token get beginToken => _literal;
   Token get endToken => _literal;
@@ -5689,15 +6203,15 @@
    * Set the token representing the literal to the given token.
    * @param literal the token representing the literal
    */
-  void set literal4(Token literal) {
-    this._literal = literal;
+  void set literal(Token literal4) {
+    this._literal = literal4;
   }
   /**
    * Set the value of the literal to the given value.
    * @param value the value of the literal
    */
-  void set value6(int value) {
-    this._value = value;
+  void set value(int value6) {
+    this._value = value6;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
   }
@@ -5737,11 +6251,18 @@
    * @param expression the expression to be evaluated for the value to be converted into a string
    * @param rightBracket the right curly bracket
    */
-  InterpolationExpression(Token leftBracket, Expression expression, Token rightBracket) {
+  InterpolationExpression.full(Token leftBracket, Expression expression, Token rightBracket) {
     this._leftBracket = leftBracket;
     this._expression = becomeParentOf(expression);
     this._rightBracket = rightBracket;
   }
+  /**
+   * Initialize a newly created interpolation expression.
+   * @param leftBracket the left curly bracket
+   * @param expression the expression to be evaluated for the value to be converted into a string
+   * @param rightBracket the right curly bracket
+   */
+  InterpolationExpression({Token leftBracket, Expression expression, Token rightBracket}) : this.full(leftBracket, expression, rightBracket);
   accept(ASTVisitor visitor) => visitor.visitInterpolationExpression(this);
   Token get beginToken => _leftBracket;
   Token get endToken {
@@ -5770,22 +6291,22 @@
    * expression.
    * @param expression the expression to be evaluated for the value to be converted into a string
    */
-  void set expression6(Expression expression) {
-    this._expression = becomeParentOf(expression);
+  void set expression(Expression expression6) {
+    this._expression = becomeParentOf(expression6);
   }
   /**
    * Set the left curly bracket to the given token.
    * @param leftBracket the left curly bracket
    */
-  void set leftBracket5(Token leftBracket) {
-    this._leftBracket = leftBracket;
+  void set leftBracket(Token leftBracket6) {
+    this._leftBracket = leftBracket6;
   }
   /**
    * Set the right curly bracket to the given token.
    * @param rightBracket the right curly bracket
    */
-  void set rightBracket5(Token rightBracket) {
-    this._rightBracket = rightBracket;
+  void set rightBracket(Token rightBracket6) {
+    this._rightBracket = rightBracket6;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_expression, visitor);
@@ -5813,10 +6334,16 @@
    * @param the characters that will be added to the string
    * @param value the value of the literal
    */
-  InterpolationString(Token contents, String value) {
+  InterpolationString.full(Token contents, String value) {
     this._contents = contents;
     this._value = value;
   }
+  /**
+   * Initialize a newly created string of characters that are part of a string interpolation.
+   * @param the characters that will be added to the string
+   * @param value the value of the literal
+   */
+  InterpolationString({Token contents, String value}) : this.full(contents, value);
   accept(ASTVisitor visitor) => visitor.visitInterpolationString(this);
   Token get beginToken => _contents;
   /**
@@ -5834,14 +6361,14 @@
    * Set the characters that will be added to the string to those in the given string.
    * @param string the characters that will be added to the string
    */
-  void set contents2(Token string) {
+  void set contents(Token string) {
     _contents = string;
   }
   /**
    * Set the value of the literal to the given string.
    * @param string the value of the literal
    */
-  void set value7(String string) {
+  void set value(String string) {
     _value = string;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -5876,12 +6403,20 @@
    * @param notOperator the not operator, or {@code null} if the sense of the test is not negated
    * @param type the name of the type being tested for
    */
-  IsExpression(Expression expression, Token isOperator, Token notOperator, TypeName type) {
+  IsExpression.full(Expression expression, Token isOperator, Token notOperator, TypeName type) {
     this._expression = becomeParentOf(expression);
     this._isOperator = isOperator;
     this._notOperator = notOperator;
     this._type = becomeParentOf(type);
   }
+  /**
+   * Initialize a newly created is expression.
+   * @param expression the expression used to compute the value whose type is being tested
+   * @param isOperator the is operator
+   * @param notOperator the not operator, or {@code null} if the sense of the test is not negated
+   * @param type the name of the type being tested for
+   */
+  IsExpression({Expression expression, Token isOperator, Token notOperator, TypeName type}) : this.full(expression, isOperator, notOperator, type);
   accept(ASTVisitor visitor) => visitor.visitIsExpression(this);
   Token get beginToken => _expression.beginToken;
   Token get endToken => _type.endToken;
@@ -5910,28 +6445,28 @@
    * expression.
    * @param expression the expression used to compute the value whose type is being tested
    */
-  void set expression7(Expression expression) {
-    this._expression = becomeParentOf(expression);
+  void set expression(Expression expression7) {
+    this._expression = becomeParentOf(expression7);
   }
   /**
    * Set the is operator being applied to the given operator.
    * @param isOperator the is operator being applied
    */
-  void set isOperator2(Token isOperator) {
-    this._isOperator = isOperator;
+  void set isOperator(Token isOperator2) {
+    this._isOperator = isOperator2;
   }
   /**
    * Set the not operator being applied to the given operator.
    * @param notOperator the is operator being applied
    */
-  void set notOperator2(Token notOperator) {
-    this._notOperator = notOperator;
+  void set notOperator(Token notOperator2) {
+    this._notOperator = notOperator2;
   }
   /**
    * Set the name of the type being tested for to the given name.
    * @param name the name of the type being tested for
    */
-  void set type5(TypeName name) {
+  void set type(TypeName name) {
     this._type = becomeParentOf(name);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -5959,10 +6494,16 @@
    * @param label the label being applied
    * @param colon the colon that separates the label from whatever follows
    */
-  Label(SimpleIdentifier label, Token colon) {
+  Label.full(SimpleIdentifier label, Token colon) {
     this._label = becomeParentOf(label);
     this._colon = colon;
   }
+  /**
+   * Initialize a newly created label.
+   * @param label the label being applied
+   * @param colon the colon that separates the label from whatever follows
+   */
+  Label({SimpleIdentifier label, Token colon}) : this.full(label, colon);
   accept(ASTVisitor visitor) => visitor.visitLabel(this);
   Token get beginToken => _label.beginToken;
   /**
@@ -5980,15 +6521,15 @@
    * Set the colon that separates the label from the statement to the given token.
    * @param colon the colon that separates the label from the statement
    */
-  void set colon3(Token colon) {
-    this._colon = colon;
+  void set colon(Token colon3) {
+    this._colon = colon3;
   }
   /**
    * Set the label being associated with the statement to the given label.
    * @param label the label being associated with the statement
    */
-  void set label4(SimpleIdentifier label) {
-    this._label = becomeParentOf(label);
+  void set label(SimpleIdentifier label2) {
+    this._label = becomeParentOf(label2);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_label, visitor);
@@ -6014,11 +6555,17 @@
    * @param labels the labels being associated with the statement
    * @param statement the statement with which the labels are being associated
    */
-  LabeledStatement(List<Label> labels, Statement statement) {
+  LabeledStatement.full(List<Label> labels, Statement statement) {
     this._labels = new NodeList<Label>(this);
     this._labels.addAll(labels);
     this._statement = becomeParentOf(statement);
   }
+  /**
+   * Initialize a newly created labeled statement.
+   * @param labels the labels being associated with the statement
+   * @param statement the statement with which the labels are being associated
+   */
+  LabeledStatement({List<Label> labels, Statement statement}) : this.full(labels, statement);
   accept(ASTVisitor visitor) => visitor.visitLabeledStatement(this);
   Token get beginToken {
     if (!_labels.isEmpty) {
@@ -6041,8 +6588,8 @@
    * Set the statement with which the labels are being associated to the given statement.
    * @param statement the statement with which the labels are being associated
    */
-  void set statement2(Statement statement) {
-    this._statement = becomeParentOf(statement);
+  void set statement(Statement statement2) {
+    this._statement = becomeParentOf(statement2);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     _labels.accept(visitor);
@@ -6076,11 +6623,20 @@
    * @param name the name of the library being defined
    * @param semicolon the semicolon terminating the directive
    */
-  LibraryDirective(Comment comment, List<Annotation> metadata, Token libraryToken, LibraryIdentifier name, Token semicolon) : super(comment, metadata) {
+  LibraryDirective.full(Comment comment, List<Annotation> metadata, Token libraryToken, LibraryIdentifier name, Token semicolon) : super.full(comment, metadata) {
     this._libraryToken = libraryToken;
     this._name = becomeParentOf(name);
     this._semicolon = semicolon;
   }
+  /**
+   * Initialize a newly created library directive.
+   * @param comment the documentation comment associated with this directive
+   * @param metadata the annotations associated with the directive
+   * @param libraryToken the token representing the 'library' token
+   * @param name the name of the library being defined
+   * @param semicolon the semicolon terminating the directive
+   */
+  LibraryDirective({Comment comment, List<Annotation> metadata, Token libraryToken, LibraryIdentifier name, Token semicolon}) : this.full(comment, metadata, libraryToken, name, semicolon);
   accept(ASTVisitor visitor) => visitor.visitLibraryDirective(this);
   Token get endToken => _semicolon;
   Token get keyword => _libraryToken;
@@ -6103,22 +6659,22 @@
    * Set the token representing the 'library' token to the given token.
    * @param libraryToken the token representing the 'library' token
    */
-  void set libraryToken2(Token libraryToken) {
-    this._libraryToken = libraryToken;
+  void set libraryToken(Token libraryToken2) {
+    this._libraryToken = libraryToken2;
   }
   /**
    * Set the name of the library being defined to the given name.
    * @param name the name of the library being defined
    */
-  void set name9(LibraryIdentifier name) {
-    this._name = becomeParentOf(name);
+  void set name(LibraryIdentifier name6) {
+    this._name = becomeParentOf(name6);
   }
   /**
    * Set the semicolon terminating the directive to the given token.
    * @param semicolon the semicolon terminating the directive
    */
-  void set semicolon11(Token semicolon) {
-    this._semicolon = semicolon;
+  void set semicolon(Token semicolon11) {
+    this._semicolon = semicolon11;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     super.visitChildren(visitor);
@@ -6141,10 +6697,15 @@
    * Initialize a newly created prefixed identifier.
    * @param components the components of the identifier
    */
-  LibraryIdentifier(List<SimpleIdentifier> components) {
+  LibraryIdentifier.full(List<SimpleIdentifier> components) {
     this._components = new NodeList<SimpleIdentifier>(this);
     this._components.addAll(components);
   }
+  /**
+   * Initialize a newly created prefixed identifier.
+   * @param components the components of the identifier
+   */
+  LibraryIdentifier({List<SimpleIdentifier> components}) : this.full(components);
   accept(ASTVisitor visitor) => visitor.visitLibraryIdentifier(this);
   Token get beginToken => _components.beginToken;
   /**
@@ -6199,12 +6760,22 @@
    * @param elements the expressions used to compute the elements of the list
    * @param rightBracket the right square bracket
    */
-  ListLiteral(Token modifier, TypeArgumentList typeArguments, Token leftBracket, List<Expression> elements, Token rightBracket) : super(modifier, typeArguments) {
+  ListLiteral.full(Token modifier, TypeArgumentList typeArguments, Token leftBracket, List<Expression> elements, Token rightBracket) : super.full(modifier, typeArguments) {
     this._elements = new NodeList<Expression>(this);
     this._leftBracket = leftBracket;
     this._elements.addAll(elements);
     this._rightBracket = rightBracket;
   }
+  /**
+   * Initialize a newly created list literal.
+   * @param modifier the const modifier associated with this literal
+   * @param typeArguments the type argument associated with this literal, or {@code null} if no type
+   * arguments were declared
+   * @param leftBracket the left square bracket
+   * @param elements the expressions used to compute the elements of the list
+   * @param rightBracket the right square bracket
+   */
+  ListLiteral({Token modifier, TypeArgumentList typeArguments, Token leftBracket, List<Expression> elements, Token rightBracket}) : this.full(modifier, typeArguments, leftBracket, elements, rightBracket);
   accept(ASTVisitor visitor) => visitor.visitListLiteral(this);
   Token get beginToken {
     Token token = modifier;
@@ -6237,14 +6808,14 @@
    * Set the left square bracket to the given token.
    * @param bracket the left square bracket
    */
-  void set leftBracket6(Token bracket) {
+  void set leftBracket(Token bracket) {
     _leftBracket = bracket;
   }
   /**
    * Set the right square bracket to the given token.
    * @param bracket the right square bracket
    */
-  void set rightBracket6(Token bracket) {
+  void set rightBracket(Token bracket) {
     _rightBracket = bracket;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -6289,12 +6860,22 @@
    * @param entries the entries in the map
    * @param rightBracket the right curly bracket
    */
-  MapLiteral(Token modifier, TypeArgumentList typeArguments, Token leftBracket, List<MapLiteralEntry> entries, Token rightBracket) : super(modifier, typeArguments) {
+  MapLiteral.full(Token modifier, TypeArgumentList typeArguments, Token leftBracket, List<MapLiteralEntry> entries, Token rightBracket) : super.full(modifier, typeArguments) {
     this._entries = new NodeList<MapLiteralEntry>(this);
     this._leftBracket = leftBracket;
     this._entries.addAll(entries);
     this._rightBracket = rightBracket;
   }
+  /**
+   * Initialize a newly created map literal.
+   * @param modifier the const modifier associated with this literal
+   * @param typeArguments the type argument associated with this literal, or {@code null} if no type
+   * arguments were declared
+   * @param leftBracket the left curly bracket
+   * @param entries the entries in the map
+   * @param rightBracket the right curly bracket
+   */
+  MapLiteral({Token modifier, TypeArgumentList typeArguments, Token leftBracket, List<MapLiteralEntry> entries, Token rightBracket}) : this.full(modifier, typeArguments, leftBracket, entries, rightBracket);
   accept(ASTVisitor visitor) => visitor.visitMapLiteral(this);
   Token get beginToken {
     Token token = modifier;
@@ -6327,14 +6908,14 @@
    * Set the left curly bracket to the given token.
    * @param bracket the left curly bracket
    */
-  void set leftBracket7(Token bracket) {
+  void set leftBracket(Token bracket) {
     _leftBracket = bracket;
   }
   /**
    * Set the right curly bracket to the given token.
    * @param bracket the right curly bracket
    */
-  void set rightBracket7(Token bracket) {
+  void set rightBracket(Token bracket) {
     _rightBracket = bracket;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -6367,11 +6948,18 @@
    * @param separator the colon that separates the key from the value
    * @param value the expression computing the value that will be associated with the key
    */
-  MapLiteralEntry(StringLiteral key, Token separator, Expression value) {
+  MapLiteralEntry.full(StringLiteral key, Token separator, Expression value) {
     this._key = becomeParentOf(key);
     this._separator = separator;
     this._value = becomeParentOf(value);
   }
+  /**
+   * Initialize a newly created map literal entry.
+   * @param key the key with which the value will be associated
+   * @param separator the colon that separates the key from the value
+   * @param value the expression computing the value that will be associated with the key
+   */
+  MapLiteralEntry({StringLiteral key, Token separator, Expression value}) : this.full(key, separator, value);
   accept(ASTVisitor visitor) => visitor.visitMapLiteralEntry(this);
   Token get beginToken => _key.beginToken;
   Token get endToken => _value.endToken;
@@ -6394,22 +6982,22 @@
    * Set the key with which the value will be associated to the given string.
    * @param string the key with which the value will be associated
    */
-  void set key2(StringLiteral string) {
+  void set key(StringLiteral string) {
     _key = becomeParentOf(string);
   }
   /**
    * Set the colon that separates the key from the value to the given token.
    * @param separator the colon that separates the key from the value
    */
-  void set separator4(Token separator) {
-    this._separator = separator;
+  void set separator(Token separator4) {
+    this._separator = separator4;
   }
   /**
    * Set the expression computing the value that will be associated with the key to the given
    * expression.
    * @param expression the expression computing the value that will be associated with the key
    */
-  void set value8(Expression expression) {
+  void set value(Expression expression) {
     _value = becomeParentOf(expression);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -6475,7 +7063,7 @@
    * declares a getter
    * @param body the body of the method
    */
-  MethodDeclaration(Comment comment, List<Annotation> metadata, Token externalKeyword, Token modifierKeyword, TypeName returnType, Token propertyKeyword, Token operatorKeyword, Identifier name, FormalParameterList parameters, FunctionBody body) : super(comment, metadata) {
+  MethodDeclaration.full(Comment comment, List<Annotation> metadata, Token externalKeyword, Token modifierKeyword, TypeName returnType, Token propertyKeyword, Token operatorKeyword, Identifier name, FormalParameterList parameters, FunctionBody body) : super.full(comment, metadata) {
     this._externalKeyword = externalKeyword;
     this._modifierKeyword = modifierKeyword;
     this._returnType = becomeParentOf(returnType);
@@ -6485,6 +7073,21 @@
     this._parameters = becomeParentOf(parameters);
     this._body = becomeParentOf(body);
   }
+  /**
+   * Initialize a newly created method declaration.
+   * @param externalKeyword the token for the 'external' keyword
+   * @param comment the documentation comment associated with this method
+   * @param metadata the annotations associated with this method
+   * @param modifierKeyword the token representing the 'abstract' or 'static' keyword
+   * @param returnType the return type of the method
+   * @param propertyKeyword the token representing the 'get' or 'set' keyword
+   * @param operatorKeyword the token representing the 'operator' keyword
+   * @param name the name of the method
+   * @param parameters the parameters associated with the method, or {@code null} if this method
+   * declares a getter
+   * @param body the body of the method
+   */
+  MethodDeclaration({Comment comment, List<Annotation> metadata, Token externalKeyword, Token modifierKeyword, TypeName returnType, Token propertyKeyword, Token operatorKeyword, Identifier name, FormalParameterList parameters, FunctionBody body}) : this.full(comment, metadata, externalKeyword, modifierKeyword, returnType, propertyKeyword, operatorKeyword, name, parameters, body);
   accept(ASTVisitor visitor) => visitor.visitMethodDeclaration(this);
   /**
    * Return the body of the method.
@@ -6498,7 +7101,7 @@
    * declaration of either a getter or a setter.
    * @return the element associated with this method
    */
-  ExecutableElement get element => _name != null ? _name.element as ExecutableElement : null;
+  ExecutableElement get element => _name != null ? (_name.element as ExecutableElement) : null;
   Token get endToken => _body.endToken;
   /**
    * Return the token for the 'external' keyword, or {@code null} if the constructor is not
@@ -6544,7 +7147,7 @@
    * Return {@code true} if this method declares a getter.
    * @return {@code true} if this method declares a getter
    */
-  bool isGetter() => _propertyKeyword != null && (_propertyKeyword as KeywordToken).keyword == Keyword.GET;
+  bool isGetter() => _propertyKeyword != null && identical(((_propertyKeyword as KeywordToken)).keyword, Keyword.GET);
   /**
    * Return {@code true} if this method declares an operator.
    * @return {@code true} if this method declares an operator
@@ -6554,61 +7157,61 @@
    * Return {@code true} if this method declares a setter.
    * @return {@code true} if this method declares a setter
    */
-  bool isSetter() => _propertyKeyword != null && (_propertyKeyword as KeywordToken).keyword == Keyword.SET;
+  bool isSetter() => _propertyKeyword != null && identical(((_propertyKeyword as KeywordToken)).keyword, Keyword.SET);
   /**
    * Set the body of the method to the given function body.
    * @param functionBody the body of the method
    */
-  void set body8(FunctionBody functionBody) {
+  void set body(FunctionBody functionBody) {
     _body = becomeParentOf(functionBody);
   }
   /**
    * Set the token for the 'external' keyword to the given token.
    * @param externalKeyword the token for the 'external' keyword
    */
-  void set externalKeyword4(Token externalKeyword) {
-    this._externalKeyword = externalKeyword;
+  void set externalKeyword(Token externalKeyword4) {
+    this._externalKeyword = externalKeyword4;
   }
   /**
    * Set the token representing the 'abstract' or 'static' keyword to the given token.
    * @param modifierKeyword the token representing the 'abstract' or 'static' keyword
    */
-  void set modifierKeyword2(Token modifierKeyword) {
-    this._modifierKeyword = modifierKeyword;
+  void set modifierKeyword(Token modifierKeyword2) {
+    this._modifierKeyword = modifierKeyword2;
   }
   /**
    * Set the name of the method to the given identifier.
    * @param identifier the name of the method
    */
-  void set name10(Identifier identifier) {
+  void set name(Identifier identifier) {
     _name = becomeParentOf(identifier);
   }
   /**
    * Set the token representing the 'operator' keyword to the given token.
    * @param operatorKeyword the token representing the 'operator' keyword
    */
-  void set operatorKeyword2(Token operatorKeyword) {
-    this._operatorKeyword = operatorKeyword;
+  void set operatorKeyword(Token operatorKeyword2) {
+    this._operatorKeyword = operatorKeyword2;
   }
   /**
    * Set the parameters associated with the method to the given list of parameters.
    * @param parameters the parameters associated with the method
    */
-  void set parameters6(FormalParameterList parameters) {
-    this._parameters = becomeParentOf(parameters);
+  void set parameters(FormalParameterList parameters6) {
+    this._parameters = becomeParentOf(parameters6);
   }
   /**
    * Set the token representing the 'get' or 'set' keyword to the given token.
    * @param propertyKeyword the token representing the 'get' or 'set' keyword
    */
-  void set propertyKeyword3(Token propertyKeyword) {
-    this._propertyKeyword = propertyKeyword;
+  void set propertyKeyword(Token propertyKeyword3) {
+    this._propertyKeyword = propertyKeyword3;
   }
   /**
    * Set the return type of the method to the given type name.
    * @param typeName the return type of the method
    */
-  void set returnType6(TypeName typeName) {
+  void set returnType(TypeName typeName) {
     _returnType = becomeParentOf(typeName);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -6665,12 +7268,20 @@
    * @param methodName the name of the method being invoked
    * @param argumentList the list of arguments to the method
    */
-  MethodInvocation(Expression target, Token period, SimpleIdentifier methodName, ArgumentList argumentList) {
+  MethodInvocation.full(Expression target, Token period, SimpleIdentifier methodName, ArgumentList argumentList) {
     this._target = becomeParentOf(target);
     this._period = period;
     this._methodName = becomeParentOf(methodName);
     this._argumentList = becomeParentOf(argumentList);
   }
+  /**
+   * Initialize a newly created method invocation.
+   * @param target the expression producing the object on which the method is defined
+   * @param period the period that separates the target from the method name
+   * @param methodName the name of the method being invoked
+   * @param argumentList the list of arguments to the method
+   */
+  MethodInvocation({Expression target, Token period, SimpleIdentifier methodName, ArgumentList argumentList}) : this.full(target, period, methodName, argumentList);
   accept(ASTVisitor visitor) => visitor.visitMethodInvocation(this);
   /**
    * Return the list of arguments to the method.
@@ -6712,7 +7323,7 @@
         }
         ancestor = ancestor.parent;
       }
-      return (ancestor as CascadeExpression).target;
+      return ((ancestor as CascadeExpression)).target;
     }
     return _target;
   }
@@ -6729,33 +7340,33 @@
    * expression is not stored locally but is stored in the nearest ancestor that is a{@link CascadeExpression}.
    * @return {@code true} if this expression is cascaded
    */
-  bool isCascaded() => _period != null && _period.type == TokenType.PERIOD_PERIOD;
+  bool isCascaded() => _period != null && identical(_period.type, TokenType.PERIOD_PERIOD);
   /**
    * Set the list of arguments to the method to the given list.
    * @param argumentList the list of arguments to the method
    */
-  void set argumentList7(ArgumentList argumentList) {
-    this._argumentList = becomeParentOf(argumentList);
+  void set argumentList(ArgumentList argumentList7) {
+    this._argumentList = becomeParentOf(argumentList7);
   }
   /**
    * Set the name of the method being invoked to the given identifier.
    * @param identifier the name of the method being invoked
    */
-  void set methodName2(SimpleIdentifier identifier) {
+  void set methodName(SimpleIdentifier identifier) {
     _methodName = becomeParentOf(identifier);
   }
   /**
    * Set the period that separates the target from the method name to the given token.
    * @param period the period that separates the target from the method name
    */
-  void set period8(Token period) {
-    this._period = period;
+  void set period(Token period9) {
+    this._period = period9;
   }
   /**
    * Set the expression producing the object on which the method is defined to the given expression.
    * @param expression the expression producing the object on which the method is defined
    */
-  void set target3(Expression expression) {
+  void set target(Expression expression) {
     _target = becomeParentOf(expression);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -6784,10 +7395,16 @@
    * @param name the name associated with the expression
    * @param expression the expression with which the name is associated
    */
-  NamedExpression(Label name, Expression expression) {
+  NamedExpression.full(Label name, Expression expression) {
     this._name = becomeParentOf(name);
     this._expression = becomeParentOf(expression);
   }
+  /**
+   * Initialize a newly created named expression.
+   * @param name the name associated with the expression
+   * @param expression the expression with which the name is associated
+   */
+  NamedExpression({Label name, Expression expression}) : this.full(name, expression);
   accept(ASTVisitor visitor) => visitor.visitNamedExpression(this);
   Token get beginToken => _name.beginToken;
   Token get endToken => _expression.endToken;
@@ -6805,14 +7422,14 @@
    * Set the expression with which the name is associated to the given expression.
    * @param expression the expression with which the name is associated
    */
-  void set expression8(Expression expression) {
-    this._expression = becomeParentOf(expression);
+  void set expression(Expression expression8) {
+    this._expression = becomeParentOf(expression8);
   }
   /**
    * Set the name associated with the expression to the given identifier.
    * @param identifier the name associated with the expression
    */
-  void set name11(Label identifier) {
+  void set name(Label identifier) {
     _name = becomeParentOf(identifier);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -6826,16 +7443,12 @@
  * <pre>
  * directive ::={@link ExportDirective exportDirective}| {@link ImportDirective importDirective}</pre>
  */
-abstract class NamespaceDirective extends Directive {
+abstract class NamespaceDirective extends UriBasedDirective {
   /**
    * The token representing the 'import' or 'export' keyword.
    */
   Token _keyword;
   /**
-   * The URI of the library being imported or exported.
-   */
-  StringLiteral _libraryUri;
-  /**
    * The combinators used to control which names are imported or exported.
    */
   NodeList<Combinator> _combinators;
@@ -6852,14 +7465,23 @@
    * @param combinators the combinators used to control which names are imported or exported
    * @param semicolon the semicolon terminating the directive
    */
-  NamespaceDirective(Comment comment, List<Annotation> metadata, Token keyword, StringLiteral libraryUri, List<Combinator> combinators, Token semicolon) : super(comment, metadata) {
+  NamespaceDirective.full(Comment comment, List<Annotation> metadata, Token keyword, StringLiteral libraryUri, List<Combinator> combinators, Token semicolon) : super.full(comment, metadata, libraryUri) {
     this._combinators = new NodeList<Combinator>(this);
     this._keyword = keyword;
-    this._libraryUri = becomeParentOf(libraryUri);
     this._combinators.addAll(combinators);
     this._semicolon = semicolon;
   }
   /**
+   * Initialize a newly created namespace directive.
+   * @param comment the documentation comment associated with this directive
+   * @param metadata the annotations associated with the directive
+   * @param keyword the token representing the 'import' or 'export' keyword
+   * @param libraryUri the URI of the library being imported or exported
+   * @param combinators the combinators used to control which names are imported or exported
+   * @param semicolon the semicolon terminating the directive
+   */
+  NamespaceDirective({Comment comment, List<Annotation> metadata, Token keyword, StringLiteral libraryUri, List<Combinator> combinators, Token semicolon}) : this.full(comment, metadata, keyword, libraryUri, combinators, semicolon);
+  /**
    * Return the combinators used to control how names are imported or exported.
    * @return the combinators used to control how names are imported or exported
    */
@@ -6867,11 +7489,6 @@
   Token get endToken => _semicolon;
   Token get keyword => _keyword;
   /**
-   * Return the URI of the library being imported or exported.
-   * @return the URI of the library being imported or exported
-   */
-  StringLiteral get libraryUri => _libraryUri;
-  /**
    * Return the semicolon terminating the directive.
    * @return the semicolon terminating the directive
    */
@@ -6880,22 +7497,15 @@
    * Set the token representing the 'import' or 'export' keyword to the given token.
    * @param exportToken the token representing the 'import' or 'export' keyword
    */
-  void set keyword13(Token exportToken) {
+  void set keyword(Token exportToken) {
     this._keyword = exportToken;
   }
   /**
-   * Set the URI of the library being imported or exported to the given literal.
-   * @param literal the URI of the library being imported or exported
-   */
-  void set libraryUri2(StringLiteral literal) {
-    _libraryUri = becomeParentOf(literal);
-  }
-  /**
    * Set the semicolon terminating the directive to the given token.
    * @param semicolon the semicolon terminating the directive
    */
-  void set semicolon12(Token semicolon) {
-    this._semicolon = semicolon;
+  void set semicolon(Token semicolon12) {
+    this._semicolon = semicolon12;
   }
   Token get firstTokenAfterCommentAndMetadata => _keyword;
 }
@@ -6925,13 +7535,20 @@
    * @param metadata the annotations associated with this parameter
    * @param identifier the name of the parameter being declared
    */
-  NormalFormalParameter(Comment comment, List<Annotation> metadata, SimpleIdentifier identifier) {
+  NormalFormalParameter.full(Comment comment, List<Annotation> metadata, SimpleIdentifier identifier) {
     this._metadata = new NodeList<Annotation>(this);
     this._comment = becomeParentOf(comment);
     this._metadata.addAll(metadata);
     this._identifier = becomeParentOf(identifier);
   }
   /**
+   * Initialize a newly created formal parameter.
+   * @param comment the documentation comment associated with this parameter
+   * @param metadata the annotations associated with this parameter
+   * @param identifier the name of the parameter being declared
+   */
+  NormalFormalParameter({Comment comment, List<Annotation> metadata, SimpleIdentifier identifier}) : this.full(comment, metadata, identifier);
+  /**
    * Return the documentation comment associated with this parameter, or {@code null} if this
    * parameter does not have a documentation comment associated with it.
    * @return the documentation comment associated with this parameter
@@ -6939,9 +7556,9 @@
   Comment get documentationComment => _comment;
   SimpleIdentifier get identifier => _identifier;
   ParameterKind get kind {
-    ASTNode parent6 = parent;
-    if (parent6 is DefaultFormalParameter) {
-      return (parent6 as DefaultFormalParameter).kind;
+    ASTNode parent5 = parent;
+    if (parent5 is DefaultFormalParameter) {
+      return ((parent5 as DefaultFormalParameter)).kind;
     }
     return ParameterKind.REQUIRED;
   }
@@ -6964,15 +7581,15 @@
    * Set the documentation comment associated with this parameter to the given comment
    * @param comment the documentation comment to be associated with this parameter
    */
-  void set documentationComment(Comment comment) {
-    this._comment = becomeParentOf(comment);
+  void set documentationComment(Comment comment3) {
+    this._comment = becomeParentOf(comment3);
   }
   /**
    * Set the name of the parameter being declared to the given identifier.
    * @param identifier the name of the parameter being declared
    */
-  void set identifier4(SimpleIdentifier identifier) {
-    this._identifier = becomeParentOf(identifier);
+  void set identifier(SimpleIdentifier identifier6) {
+    this._identifier = becomeParentOf(identifier6);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     if (commentIsBeforeAnnotations()) {
@@ -7026,9 +7643,14 @@
    * Initialize a newly created null literal.
    * @param token the token representing the literal
    */
-  NullLiteral(Token token) {
+  NullLiteral.full(Token token) {
     this._literal = token;
   }
+  /**
+   * Initialize a newly created null literal.
+   * @param token the token representing the literal
+   */
+  NullLiteral({Token token}) : this.full(token);
   accept(ASTVisitor visitor) => visitor.visitNullLiteral(this);
   Token get beginToken => _literal;
   Token get endToken => _literal;
@@ -7041,8 +7663,8 @@
    * Set the token representing the literal to the given token.
    * @param literal the token representing the literal
    */
-  void set literal5(Token literal) {
-    this._literal = literal;
+  void set literal(Token literal5) {
+    this._literal = literal5;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
   }
@@ -7073,11 +7695,18 @@
    * @param expression the expression within the parentheses
    * @param rightParenthesis the right parenthesis
    */
-  ParenthesizedExpression(Token leftParenthesis, Expression expression, Token rightParenthesis) {
+  ParenthesizedExpression.full(Token leftParenthesis, Expression expression, Token rightParenthesis) {
     this._leftParenthesis = leftParenthesis;
     this._expression = becomeParentOf(expression);
     this._rightParenthesis = rightParenthesis;
   }
+  /**
+   * Initialize a newly created parenthesized expression.
+   * @param leftParenthesis the left parenthesis
+   * @param expression the expression within the parentheses
+   * @param rightParenthesis the right parenthesis
+   */
+  ParenthesizedExpression({Token leftParenthesis, Expression expression, Token rightParenthesis}) : this.full(leftParenthesis, expression, rightParenthesis);
   accept(ASTVisitor visitor) => visitor.visitParenthesizedExpression(this);
   Token get beginToken => _leftParenthesis;
   Token get endToken => _rightParenthesis;
@@ -7100,21 +7729,21 @@
    * Set the expression within the parentheses to the given expression.
    * @param expression the expression within the parentheses
    */
-  void set expression9(Expression expression) {
-    this._expression = becomeParentOf(expression);
+  void set expression(Expression expression9) {
+    this._expression = becomeParentOf(expression9);
   }
   /**
    * Set the left parenthesis to the given token.
    * @param parenthesis the left parenthesis
    */
-  void set leftParenthesis10(Token parenthesis) {
+  void set leftParenthesis(Token parenthesis) {
     _leftParenthesis = parenthesis;
   }
   /**
    * Set the right parenthesis to the given token.
    * @param parenthesis the right parenthesis
    */
-  void set rightParenthesis10(Token parenthesis) {
+  void set rightParenthesis(Token parenthesis) {
     _rightParenthesis = parenthesis;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -7127,16 +7756,12 @@
  * partDirective ::={@link Annotation metadata} 'part' {@link StringLiteral partUri} ';'
  * </pre>
  */
-class PartDirective extends Directive {
+class PartDirective extends UriBasedDirective {
   /**
    * The token representing the 'part' token.
    */
   Token _partToken;
   /**
-   * The URI of the part being included.
-   */
-  StringLiteral _partUri;
-  /**
    * The semicolon terminating the directive.
    */
   Token _semicolon;
@@ -7148,11 +7773,19 @@
    * @param partUri the URI of the part being included
    * @param semicolon the semicolon terminating the directive
    */
-  PartDirective(Comment comment, List<Annotation> metadata, Token partToken, StringLiteral partUri, Token semicolon) : super(comment, metadata) {
+  PartDirective.full(Comment comment, List<Annotation> metadata, Token partToken, StringLiteral partUri, Token semicolon) : super.full(comment, metadata, partUri) {
     this._partToken = partToken;
-    this._partUri = becomeParentOf(partUri);
     this._semicolon = semicolon;
   }
+  /**
+   * Initialize a newly created part directive.
+   * @param comment the documentation comment associated with this directive
+   * @param metadata the annotations associated with the directive
+   * @param partToken the token representing the 'part' token
+   * @param partUri the URI of the part being included
+   * @param semicolon the semicolon terminating the directive
+   */
+  PartDirective({Comment comment, List<Annotation> metadata, Token partToken, StringLiteral partUri, Token semicolon}) : this.full(comment, metadata, partToken, partUri, semicolon);
   accept(ASTVisitor visitor) => visitor.visitPartDirective(this);
   Token get endToken => _semicolon;
   Token get keyword => _partToken;
@@ -7162,11 +7795,6 @@
    */
   Token get partToken => _partToken;
   /**
-   * Return the URI of the part being included.
-   * @return the URI of the part being included
-   */
-  StringLiteral get partUri => _partUri;
-  /**
    * Return the semicolon terminating the directive.
    * @return the semicolon terminating the directive
    */
@@ -7175,26 +7803,15 @@
    * Set the token representing the 'part' token to the given token.
    * @param partToken the token representing the 'part' token
    */
-  void set partToken2(Token partToken) {
-    this._partToken = partToken;
-  }
-  /**
-   * Set the URI of the part being included to the given string.
-   * @param partUri the URI of the part being included
-   */
-  void set partUri2(StringLiteral partUri) {
-    this._partUri = becomeParentOf(partUri);
+  void set partToken(Token partToken2) {
+    this._partToken = partToken2;
   }
   /**
    * Set the semicolon terminating the directive to the given token.
    * @param semicolon the semicolon terminating the directive
    */
-  void set semicolon13(Token semicolon) {
-    this._semicolon = semicolon;
-  }
-  void visitChildren(ASTVisitor<Object> visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChild(_partUri, visitor);
+  void set semicolon(Token semicolon13) {
+    this._semicolon = semicolon13;
   }
   Token get firstTokenAfterCommentAndMetadata => _partToken;
 }
@@ -7230,12 +7847,22 @@
    * @param libraryName the name of the library that the containing compilation unit is part of
    * @param semicolon the semicolon terminating the directive
    */
-  PartOfDirective(Comment comment, List<Annotation> metadata, Token partToken, Token ofToken, LibraryIdentifier libraryName, Token semicolon) : super(comment, metadata) {
+  PartOfDirective.full(Comment comment, List<Annotation> metadata, Token partToken, Token ofToken, LibraryIdentifier libraryName, Token semicolon) : super.full(comment, metadata) {
     this._partToken = partToken;
     this._ofToken = ofToken;
     this._libraryName = becomeParentOf(libraryName);
     this._semicolon = semicolon;
   }
+  /**
+   * Initialize a newly created part-of directive.
+   * @param comment the documentation comment associated with this directive
+   * @param metadata the annotations associated with the directive
+   * @param partToken the token representing the 'part' token
+   * @param ofToken the token representing the 'of' token
+   * @param libraryName the name of the library that the containing compilation unit is part of
+   * @param semicolon the semicolon terminating the directive
+   */
+  PartOfDirective({Comment comment, List<Annotation> metadata, Token partToken, Token ofToken, LibraryIdentifier libraryName, Token semicolon}) : this.full(comment, metadata, partToken, ofToken, libraryName, semicolon);
   accept(ASTVisitor visitor) => visitor.visitPartOfDirective(this);
   Token get endToken => _semicolon;
   Token get keyword => _partToken;
@@ -7263,29 +7890,29 @@
    * Set the name of the library that the containing compilation unit is part of to the given name.
    * @param libraryName the name of the library that the containing compilation unit is part of
    */
-  void set libraryName2(LibraryIdentifier libraryName) {
-    this._libraryName = becomeParentOf(libraryName);
+  void set libraryName(LibraryIdentifier libraryName2) {
+    this._libraryName = becomeParentOf(libraryName2);
   }
   /**
    * Set the token representing the 'of' token to the given token.
    * @param ofToken the token representing the 'of' token
    */
-  void set ofToken2(Token ofToken) {
-    this._ofToken = ofToken;
+  void set ofToken(Token ofToken2) {
+    this._ofToken = ofToken2;
   }
   /**
    * Set the token representing the 'part' token to the given token.
    * @param partToken the token representing the 'part' token
    */
-  void set partToken3(Token partToken) {
-    this._partToken = partToken;
+  void set partToken(Token partToken3) {
+    this._partToken = partToken3;
   }
   /**
    * Set the semicolon terminating the directive to the given token.
    * @param semicolon the semicolon terminating the directive
    */
-  void set semicolon14(Token semicolon) {
-    this._semicolon = semicolon;
+  void set semicolon(Token semicolon14) {
+    this._semicolon = semicolon14;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     super.visitChildren(visitor);
@@ -7317,10 +7944,16 @@
    * @param operand the expression computing the operand for the operator
    * @param operator the postfix operator being applied to the operand
    */
-  PostfixExpression(Expression operand, Token operator) {
+  PostfixExpression.full(Expression operand, Token operator) {
     this._operand = becomeParentOf(operand);
     this._operator = operator;
   }
+  /**
+   * Initialize a newly created postfix expression.
+   * @param operand the expression computing the operand for the operator
+   * @param operator the postfix operator being applied to the operand
+   */
+  PostfixExpression({Expression operand, Token operator}) : this.full(operand, operator);
   accept(ASTVisitor visitor) => visitor.visitPostfixExpression(this);
   Token get beginToken => _operand.beginToken;
   /**
@@ -7345,22 +7978,22 @@
    * Set the element associated with the operator to the given element.
    * @param element the element associated with the operator
    */
-  void set element13(MethodElement element) {
-    this._element = element;
+  void set element(MethodElement element14) {
+    this._element = element14;
   }
   /**
    * Set the expression computing the operand for the operator to the given expression.
    * @param expression the expression computing the operand for the operator
    */
-  void set operand2(Expression expression) {
+  void set operand(Expression expression) {
     _operand = becomeParentOf(expression);
   }
   /**
    * Set the postfix operator being applied to the operand to the given operator.
    * @param operator the postfix operator being applied to the operand
    */
-  void set operator4(Token operator) {
-    this._operator = operator;
+  void set operator(Token operator4) {
+    this._operator = operator4;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_operand, visitor);
@@ -7390,10 +8023,16 @@
    * @param operator the prefix operator being applied to the operand
    * @param operand the expression computing the operand for the operator
    */
-  PrefixExpression(Token operator, Expression operand) {
+  PrefixExpression.full(Token operator, Expression operand) {
     this._operator = operator;
     this._operand = becomeParentOf(operand);
   }
+  /**
+   * Initialize a newly created prefix expression.
+   * @param operator the prefix operator being applied to the operand
+   * @param operand the expression computing the operand for the operator
+   */
+  PrefixExpression({Token operator, Expression operand}) : this.full(operator, operand);
   accept(ASTVisitor visitor) => visitor.visitPrefixExpression(this);
   Token get beginToken => _operator;
   /**
@@ -7418,22 +8057,22 @@
    * Set the element associated with the operator to the given element.
    * @param element the element associated with the operator
    */
-  void set element14(MethodElement element) {
-    this._element = element;
+  void set element(MethodElement element15) {
+    this._element = element15;
   }
   /**
    * Set the expression computing the operand for the operator to the given expression.
    * @param expression the expression computing the operand for the operator
    */
-  void set operand3(Expression expression) {
+  void set operand(Expression expression) {
     _operand = becomeParentOf(expression);
   }
   /**
    * Set the prefix operator being applied to the operand to the given operator.
    * @param operator the prefix operator being applied to the operand
    */
-  void set operator5(Token operator) {
-    this._operator = operator;
+  void set operator(Token operator5) {
+    this._operator = operator5;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_operand, visitor);
@@ -7465,11 +8104,18 @@
    * @param period the period used to separate the prefix from the identifier
    * @param identifier the prefix associated with the library in which the identifier is defined
    */
-  PrefixedIdentifier(SimpleIdentifier prefix, Token period, SimpleIdentifier identifier) {
+  PrefixedIdentifier.full(SimpleIdentifier prefix, Token period, SimpleIdentifier identifier) {
     this._prefix = becomeParentOf(prefix);
     this._period = period;
     this._identifier = becomeParentOf(identifier);
   }
+  /**
+   * Initialize a newly created prefixed identifier.
+   * @param prefix the identifier being prefixed
+   * @param period the period used to separate the prefix from the identifier
+   * @param identifier the prefix associated with the library in which the identifier is defined
+   */
+  PrefixedIdentifier({SimpleIdentifier prefix, Token period, SimpleIdentifier identifier}) : this.full(prefix, period, identifier);
   accept(ASTVisitor visitor) => visitor.visitPrefixedIdentifier(this);
   Token get beginToken => _prefix.beginToken;
   Token get endToken => _identifier.endToken;
@@ -7493,22 +8139,22 @@
    * Set the identifier being prefixed to the given identifier.
    * @param identifier the identifier being prefixed
    */
-  void set identifier5(SimpleIdentifier identifier) {
-    this._identifier = becomeParentOf(identifier);
+  void set identifier(SimpleIdentifier identifier7) {
+    this._identifier = becomeParentOf(identifier7);
   }
   /**
    * Set the period used to separate the prefix from the identifier to the given token.
    * @param period the period used to separate the prefix from the identifier
    */
-  void set period9(Token period) {
-    this._period = period;
+  void set period(Token period10) {
+    this._period = period10;
   }
   /**
    * Set the prefix associated with the library in which the identifier is defined to the given
    * identifier.
    * @param identifier the prefix associated with the library in which the identifier is defined
    */
-  void set prefix3(SimpleIdentifier identifier) {
+  void set prefix(SimpleIdentifier identifier) {
     _prefix = becomeParentOf(identifier);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -7543,11 +8189,18 @@
    * @param operator the property access operator
    * @param propertyName the name of the property being accessed
    */
-  PropertyAccess(Expression target, Token operator, SimpleIdentifier propertyName) {
+  PropertyAccess.full(Expression target, Token operator, SimpleIdentifier propertyName) {
     this._target = becomeParentOf(target);
     this._operator = operator;
     this._propertyName = becomeParentOf(propertyName);
   }
+  /**
+   * Initialize a newly created property access expression.
+   * @param target the expression computing the object defining the property being accessed
+   * @param operator the property access operator
+   * @param propertyName the name of the property being accessed
+   */
+  PropertyAccess({Expression target, Token operator, SimpleIdentifier propertyName}) : this.full(target, operator, propertyName);
   accept(ASTVisitor visitor) => visitor.visitPropertyAccess(this);
   Token get beginToken {
     if (_target != null) {
@@ -7583,7 +8236,7 @@
         }
         ancestor = ancestor.parent;
       }
-      return (ancestor as CascadeExpression).target;
+      return ((ancestor as CascadeExpression)).target;
     }
     return _target;
   }
@@ -7599,19 +8252,19 @@
    * expression is not stored locally but is stored in the nearest ancestor that is a{@link CascadeExpression}.
    * @return {@code true} if this expression is cascaded
    */
-  bool isCascaded() => _operator != null && _operator.type == TokenType.PERIOD_PERIOD;
+  bool isCascaded() => _operator != null && identical(_operator.type, TokenType.PERIOD_PERIOD);
   /**
    * Set the property access operator to the given token.
    * @param operator the property access operator
    */
-  void set operator6(Token operator) {
-    this._operator = operator;
+  void set operator(Token operator6) {
+    this._operator = operator6;
   }
   /**
    * Set the name of the property being accessed to the given identifier.
    * @param identifier the name of the property being accessed
    */
-  void set propertyName2(SimpleIdentifier identifier) {
+  void set propertyName(SimpleIdentifier identifier) {
     _propertyName = becomeParentOf(identifier);
   }
   /**
@@ -7619,7 +8272,7 @@
    * expression.
    * @param expression the expression computing the object defining the property being accessed
    */
-  void set target4(Expression expression) {
+  void set target(Expression expression) {
     _target = becomeParentOf(expression);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -7654,6 +8307,11 @@
    */
   ArgumentList _argumentList;
   /**
+   * The element associated with the constructor, or {@code null} if the AST structure has not been
+   * resolved or if the constructor could not be resolved.
+   */
+  ConstructorElement _element;
+  /**
    * Initialize a newly created redirecting invocation to invoke the constructor with the given name
    * with the given arguments.
    * @param keyword the token for the 'this' keyword
@@ -7661,12 +8319,21 @@
    * @param constructorName the name of the constructor that is being invoked
    * @param argumentList the list of arguments to the constructor
    */
-  RedirectingConstructorInvocation(Token keyword, Token period, SimpleIdentifier constructorName, ArgumentList argumentList) {
+  RedirectingConstructorInvocation.full(Token keyword, Token period, SimpleIdentifier constructorName, ArgumentList argumentList) {
     this._keyword = keyword;
     this._period = period;
     this._constructorName = becomeParentOf(constructorName);
     this._argumentList = becomeParentOf(argumentList);
   }
+  /**
+   * Initialize a newly created redirecting invocation to invoke the constructor with the given name
+   * with the given arguments.
+   * @param keyword the token for the 'this' keyword
+   * @param period the token for the period before the name of the constructor that is being invoked
+   * @param constructorName the name of the constructor that is being invoked
+   * @param argumentList the list of arguments to the constructor
+   */
+  RedirectingConstructorInvocation({Token keyword, Token period, SimpleIdentifier constructorName, ArgumentList argumentList}) : this.full(keyword, period, constructorName, argumentList);
   accept(ASTVisitor visitor) => visitor.visitRedirectingConstructorInvocation(this);
   /**
    * Return the list of arguments to the constructor.
@@ -7680,6 +8347,12 @@
    * @return the name of the constructor that is being invoked
    */
   SimpleIdentifier get constructorName => _constructorName;
+  /**
+   * Return the element associated with the constructor, or {@code null} if the AST structure has
+   * not been resolved or if the constructor could not be resolved.
+   * @return the element associated with the super constructor
+   */
+  ConstructorElement get element => _element;
   Token get endToken => _argumentList.endToken;
   /**
    * Return the token for the 'this' keyword.
@@ -7695,30 +8368,37 @@
    * Set the list of arguments to the constructor to the given list.
    * @param argumentList the list of arguments to the constructor
    */
-  void set argumentList8(ArgumentList argumentList) {
-    this._argumentList = becomeParentOf(argumentList);
+  void set argumentList(ArgumentList argumentList8) {
+    this._argumentList = becomeParentOf(argumentList8);
   }
   /**
    * Set the name of the constructor that is being invoked to the given identifier.
    * @param identifier the name of the constructor that is being invoked
    */
-  void set constructorName4(SimpleIdentifier identifier) {
+  void set constructorName(SimpleIdentifier identifier) {
     _constructorName = becomeParentOf(identifier);
   }
   /**
+   * Set the element associated with the constructor to the given element.
+   * @param element the element associated with the constructor
+   */
+  void set element(ConstructorElement element16) {
+    this._element = element16;
+  }
+  /**
    * Set the token for the 'this' keyword to the given token.
    * @param keyword the token for the 'this' keyword
    */
-  void set keyword14(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword13) {
+    this._keyword = keyword13;
   }
   /**
    * Set the token for the period before the name of the constructor that is being invoked to the
    * given token.
    * @param period the token for the period before the name of the constructor that is being invoked
    */
-  void set period10(Token period) {
-    this._period = period;
+  void set period(Token period11) {
+    this._period = period11;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_constructorName, visitor);
@@ -7752,11 +8432,18 @@
    * @param expression the expression computing the value to be returned
    * @param semicolon the semicolon terminating the statement
    */
-  ReturnStatement(Token keyword, Expression expression, Token semicolon) {
+  ReturnStatement.full(Token keyword, Expression expression, Token semicolon) {
     this._keyword = keyword;
     this._expression = becomeParentOf(expression);
     this._semicolon = semicolon;
   }
+  /**
+   * Initialize a newly created return statement.
+   * @param keyword the token representing the 'return' keyword
+   * @param expression the expression computing the value to be returned
+   * @param semicolon the semicolon terminating the statement
+   */
+  ReturnStatement({Token keyword, Expression expression, Token semicolon}) : this.full(keyword, expression, semicolon);
   accept(ASTVisitor visitor) => visitor.visitReturnStatement(this);
   Token get beginToken => _keyword;
   Token get endToken => _semicolon;
@@ -7780,22 +8467,22 @@
    * Set the expression computing the value to be returned to the given expression.
    * @param expression the expression computing the value to be returned
    */
-  void set expression10(Expression expression) {
-    this._expression = becomeParentOf(expression);
+  void set expression(Expression expression10) {
+    this._expression = becomeParentOf(expression10);
   }
   /**
    * Set the token representing the 'return' keyword to the given token.
    * @param keyword the token representing the 'return' keyword
    */
-  void set keyword15(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword14) {
+    this._keyword = keyword14;
   }
   /**
    * Set the semicolon terminating the statement to the given token.
    * @param semicolon the semicolon terminating the statement
    */
-  void set semicolon15(Token semicolon) {
-    this._semicolon = semicolon;
+  void set semicolon(Token semicolon15) {
+    this._semicolon = semicolon15;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_expression, visitor);
@@ -7818,9 +8505,14 @@
    * Initialize a newly created script tag.
    * @param scriptTag the token representing this script tag
    */
-  ScriptTag(Token scriptTag) {
+  ScriptTag.full(Token scriptTag) {
     this._scriptTag = scriptTag;
   }
+  /**
+   * Initialize a newly created script tag.
+   * @param scriptTag the token representing this script tag
+   */
+  ScriptTag({Token scriptTag}) : this.full(scriptTag);
   accept(ASTVisitor visitor) => visitor.visitScriptTag(this);
   Token get beginToken => _scriptTag;
   Token get endToken => _scriptTag;
@@ -7833,8 +8525,8 @@
    * Set the token representing this script tag to the given script tag.
    * @param scriptTag the token representing this script tag
    */
-  void set scriptTag3(Token scriptTag) {
-    this._scriptTag = scriptTag;
+  void set scriptTag(Token scriptTag3) {
+    this._scriptTag = scriptTag3;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
   }
@@ -7857,10 +8549,16 @@
    * @param keyword the comma introducing the combinator
    * @param shownNames the list of names from the library that are made visible by this combinator
    */
-  ShowCombinator(Token keyword, List<SimpleIdentifier> shownNames) : super(keyword) {
+  ShowCombinator.full(Token keyword, List<SimpleIdentifier> shownNames) : super.full(keyword) {
     this._shownNames = new NodeList<SimpleIdentifier>(this);
     this._shownNames.addAll(shownNames);
   }
+  /**
+   * Initialize a newly created import show combinator.
+   * @param keyword the comma introducing the combinator
+   * @param shownNames the list of names from the library that are made visible by this combinator
+   */
+  ShowCombinator({Token keyword, List<SimpleIdentifier> shownNames}) : this.full(keyword, shownNames);
   accept(ASTVisitor visitor) => visitor.visitShowCombinator(this);
   Token get endToken => _shownNames.endToken;
   /**
@@ -7897,10 +8595,19 @@
    * @param type the name of the declared type of the parameter
    * @param identifier the name of the parameter being declared
    */
-  SimpleFormalParameter(Comment comment, List<Annotation> metadata, Token keyword, TypeName type, SimpleIdentifier identifier) : super(comment, metadata, identifier) {
+  SimpleFormalParameter.full(Comment comment, List<Annotation> metadata, Token keyword, TypeName type, SimpleIdentifier identifier) : super.full(comment, metadata, identifier) {
     this._keyword = keyword;
     this._type = becomeParentOf(type);
   }
+  /**
+   * Initialize a newly created formal parameter.
+   * @param comment the documentation comment associated with this parameter
+   * @param metadata the annotations associated with this parameter
+   * @param keyword the token representing either the 'final', 'const' or 'var' keyword
+   * @param type the name of the declared type of the parameter
+   * @param identifier the name of the parameter being declared
+   */
+  SimpleFormalParameter({Comment comment, List<Annotation> metadata, Token keyword, TypeName type, SimpleIdentifier identifier}) : this.full(comment, metadata, keyword, type, identifier);
   accept(ASTVisitor visitor) => visitor.visitSimpleFormalParameter(this);
   Token get beginToken {
     if (_keyword != null) {
@@ -7922,20 +8629,20 @@
    * @return the name of the declared type of the parameter
    */
   TypeName get type => _type;
-  bool isConst() => (_keyword is KeywordToken) && (_keyword as KeywordToken).keyword == Keyword.CONST;
-  bool isFinal() => (_keyword is KeywordToken) && (_keyword as KeywordToken).keyword == Keyword.FINAL;
+  bool isConst() => (_keyword is KeywordToken) && identical(((_keyword as KeywordToken)).keyword, Keyword.CONST);
+  bool isFinal() => (_keyword is KeywordToken) && identical(((_keyword as KeywordToken)).keyword, Keyword.FINAL);
   /**
    * Set the token representing either the 'final', 'const' or 'var' keyword to the given token.
    * @param keyword the token representing either the 'final', 'const' or 'var' keyword
    */
-  void set keyword16(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword15) {
+    this._keyword = keyword15;
   }
   /**
    * Set the name of the declared type of the parameter to the given type name.
    * @param typeName the name of the declared type of the parameter
    */
-  void set type6(TypeName typeName) {
+  void set type(TypeName typeName) {
     _type = becomeParentOf(typeName);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -7962,9 +8669,14 @@
    * Initialize a newly created identifier.
    * @param token the token representing the identifier
    */
-  SimpleIdentifier(Token token) {
+  SimpleIdentifier.full(Token token) {
     this._token = token;
   }
+  /**
+   * Initialize a newly created identifier.
+   * @param token the token representing the identifier
+   */
+  SimpleIdentifier({Token token}) : this.full(token);
   accept(ASTVisitor visitor) => visitor.visitSimpleIdentifier(this);
   Token get beginToken => _token;
   Token get endToken => _token;
@@ -7982,19 +8694,19 @@
    * @return {@code true} if this expression is in a context where a getter will be invoked
    */
   bool inGetterContext() {
-    ASTNode parent7 = parent;
+    ASTNode parent6 = parent;
     ASTNode target = this;
-    if (parent7 is PrefixedIdentifier) {
-      PrefixedIdentifier prefixed = parent7 as PrefixedIdentifier;
-      if (prefixed.identifier != this) {
-        return false;
+    if (parent6 is PrefixedIdentifier) {
+      PrefixedIdentifier prefixed = (parent6 as PrefixedIdentifier);
+      if (identical(prefixed.prefix, this)) {
+        return true;
       }
-      parent7 = prefixed.parent;
+      parent6 = prefixed.parent;
       target = prefixed;
     }
-    if (parent7 is AssignmentExpression) {
-      AssignmentExpression expr = parent7 as AssignmentExpression;
-      if (expr.leftHandSide == target && expr.operator.type == TokenType.EQ) {
+    if (parent6 is AssignmentExpression) {
+      AssignmentExpression expr = (parent6 as AssignmentExpression);
+      if (identical(expr.leftHandSide, target) && identical(expr.operator.type, TokenType.EQ)) {
         return false;
       }
     }
@@ -8008,22 +8720,22 @@
    * @return {@code true} if this expression is in a context where a setter will be invoked
    */
   bool inSetterContext() {
-    ASTNode parent8 = parent;
+    ASTNode parent7 = parent;
     ASTNode target = this;
-    if (parent8 is PrefixedIdentifier) {
-      PrefixedIdentifier prefixed = parent8 as PrefixedIdentifier;
-      if (prefixed.identifier != this) {
+    if (parent7 is PrefixedIdentifier) {
+      PrefixedIdentifier prefixed = (parent7 as PrefixedIdentifier);
+      if (identical(prefixed.prefix, this)) {
         return false;
       }
-      parent8 = prefixed.parent;
+      parent7 = prefixed.parent;
       target = prefixed;
     }
-    if (parent8 is PrefixExpression) {
-      return (parent8 as PrefixExpression).operator.type.isIncrementOperator();
-    } else if (parent8 is PostfixExpression) {
+    if (parent7 is PrefixExpression) {
+      return ((parent7 as PrefixExpression)).operator.type.isIncrementOperator();
+    } else if (parent7 is PostfixExpression) {
       return true;
-    } else if (parent8 is AssignmentExpression) {
-      return (parent8 as AssignmentExpression).leftHandSide == target;
+    } else if (parent7 is AssignmentExpression) {
+      return identical(((parent7 as AssignmentExpression)).leftHandSide, target);
     }
     return false;
   }
@@ -8032,8 +8744,8 @@
    * Set the token representing the identifier to the given token.
    * @param token the token representing the literal
    */
-  void set token12(Token token) {
-    this._token = token;
+  void set token(Token token12) {
+    this._token = token12;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
   }
@@ -8072,10 +8784,16 @@
    * @param literal the token representing the literal
    * @param value the value of the literal
    */
-  SimpleStringLiteral(Token literal, String value) {
+  SimpleStringLiteral.full(Token literal, String value) {
     this._literal = literal;
     this._value = value;
   }
+  /**
+   * Initialize a newly created simple string literal.
+   * @param literal the token representing the literal
+   * @param value the value of the literal
+   */
+  SimpleStringLiteral({Token literal, String value}) : this.full(literal, value);
   accept(ASTVisitor visitor) => visitor.visitSimpleStringLiteral(this);
   Token get beginToken => _literal;
   Token get endToken => _literal;
@@ -8103,20 +8821,20 @@
    * Return {@code true} if this string literal is a raw string.
    * @return {@code true} if this string literal is a raw string
    */
-  bool isRaw() => _value.charCodeAt(0) == 0x40;
+  bool isRaw() => _value.codeUnitAt(0) == 0x40;
   bool isSynthetic() => _literal.isSynthetic();
   /**
    * Set the token representing the literal to the given token.
    * @param literal the token representing the literal
    */
-  void set literal6(Token literal) {
-    this._literal = literal;
+  void set literal(Token literal6) {
+    this._literal = literal6;
   }
   /**
    * Set the value of the literal to the given string.
    * @param string the value of the literal
    */
-  void set value9(String string) {
+  void set value(String string) {
     _value = string;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -8147,10 +8865,15 @@
    * Initialize a newly created string interpolation expression.
    * @param elements the elements that will be composed to produce the resulting string
    */
-  StringInterpolation(List<InterpolationElement> elements) {
+  StringInterpolation.full(List<InterpolationElement> elements) {
     this._elements = new NodeList<InterpolationElement>(this);
     this._elements.addAll(elements);
   }
+  /**
+   * Initialize a newly created string interpolation expression.
+   * @param elements the elements that will be composed to produce the resulting string
+   */
+  StringInterpolation({List<InterpolationElement> elements}) : this.full(elements);
   accept(ASTVisitor visitor) => visitor.visitStringInterpolation(this);
   Token get beginToken => _elements.beginToken;
   /**
@@ -8196,6 +8919,11 @@
    */
   ArgumentList _argumentList;
   /**
+   * The element associated with the constructor, or {@code null} if the AST structure has not been
+   * resolved or if the constructor could not be resolved.
+   */
+  ConstructorElement _element;
+  /**
    * Initialize a newly created super invocation to invoke the inherited constructor with the given
    * name with the given arguments.
    * @param keyword the token for the 'super' keyword
@@ -8203,12 +8931,21 @@
    * @param constructorName the name of the constructor that is being invoked
    * @param argumentList the list of arguments to the constructor
    */
-  SuperConstructorInvocation(Token keyword, Token period, SimpleIdentifier constructorName, ArgumentList argumentList) {
+  SuperConstructorInvocation.full(Token keyword, Token period, SimpleIdentifier constructorName, ArgumentList argumentList) {
     this._keyword = keyword;
     this._period = period;
     this._constructorName = becomeParentOf(constructorName);
     this._argumentList = becomeParentOf(argumentList);
   }
+  /**
+   * Initialize a newly created super invocation to invoke the inherited constructor with the given
+   * name with the given arguments.
+   * @param keyword the token for the 'super' keyword
+   * @param period the token for the period before the name of the constructor that is being invoked
+   * @param constructorName the name of the constructor that is being invoked
+   * @param argumentList the list of arguments to the constructor
+   */
+  SuperConstructorInvocation({Token keyword, Token period, SimpleIdentifier constructorName, ArgumentList argumentList}) : this.full(keyword, period, constructorName, argumentList);
   accept(ASTVisitor visitor) => visitor.visitSuperConstructorInvocation(this);
   /**
    * Return the list of arguments to the constructor.
@@ -8222,6 +8959,12 @@
    * @return the name of the constructor that is being invoked
    */
   SimpleIdentifier get constructorName => _constructorName;
+  /**
+   * Return the element associated with the constructor, or {@code null} if the AST structure has
+   * not been resolved or if the constructor could not be resolved.
+   * @return the element associated with the super constructor
+   */
+  ConstructorElement get element => _element;
   Token get endToken => _argumentList.endToken;
   /**
    * Return the token for the 'super' keyword.
@@ -8237,30 +8980,37 @@
    * Set the list of arguments to the constructor to the given list.
    * @param argumentList the list of arguments to the constructor
    */
-  void set argumentList9(ArgumentList argumentList) {
-    this._argumentList = becomeParentOf(argumentList);
+  void set argumentList(ArgumentList argumentList9) {
+    this._argumentList = becomeParentOf(argumentList9);
   }
   /**
    * Set the name of the constructor that is being invoked to the given identifier.
    * @param identifier the name of the constructor that is being invoked
    */
-  void set constructorName5(SimpleIdentifier identifier) {
+  void set constructorName(SimpleIdentifier identifier) {
     _constructorName = becomeParentOf(identifier);
   }
   /**
+   * Set the element associated with the constructor to the given element.
+   * @param element the element associated with the constructor
+   */
+  void set element(ConstructorElement element17) {
+    this._element = element17;
+  }
+  /**
    * Set the token for the 'super' keyword to the given token.
    * @param keyword the token for the 'super' keyword
    */
-  void set keyword17(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword16) {
+    this._keyword = keyword16;
   }
   /**
    * Set the token for the period before the name of the constructor that is being invoked to the
    * given token.
    * @param period the token for the period before the name of the constructor that is being invoked
    */
-  void set period11(Token period) {
-    this._period = period;
+  void set period(Token period12) {
+    this._period = period12;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_constructorName, visitor);
@@ -8283,9 +9033,14 @@
    * Initialize a newly created super expression.
    * @param keyword the token representing the keyword
    */
-  SuperExpression(Token keyword) {
+  SuperExpression.full(Token keyword) {
     this._keyword = keyword;
   }
+  /**
+   * Initialize a newly created super expression.
+   * @param keyword the token representing the keyword
+   */
+  SuperExpression({Token keyword}) : this.full(keyword);
   accept(ASTVisitor visitor) => visitor.visitSuperExpression(this);
   Token get beginToken => _keyword;
   Token get endToken => _keyword;
@@ -8298,8 +9053,8 @@
    * Set the token representing the keyword to the given token.
    * @param keyword the token representing the keyword
    */
-  void set keyword18(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword17) {
+    this._keyword = keyword17;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
   }
@@ -8322,9 +9077,18 @@
    * @param colon the colon separating the keyword or the expression from the statements
    * @param statements the statements that will be executed if this switch member is selected
    */
-  SwitchCase(List<Label> labels, Token keyword, Expression expression, Token colon, List<Statement> statements) : super(labels, keyword, colon, statements) {
+  SwitchCase.full(List<Label> labels, Token keyword, Expression expression, Token colon, List<Statement> statements) : super.full(labels, keyword, colon, statements) {
     this._expression = becomeParentOf(expression);
   }
+  /**
+   * Initialize a newly created switch case.
+   * @param labels the labels associated with the switch member
+   * @param keyword the token representing the 'case' or 'default' keyword
+   * @param expression the expression controlling whether the statements will be executed
+   * @param colon the colon separating the keyword or the expression from the statements
+   * @param statements the statements that will be executed if this switch member is selected
+   */
+  SwitchCase({List<Label> labels, Token keyword, Expression expression, Token colon, List<Statement> statements}) : this.full(labels, keyword, expression, colon, statements);
   accept(ASTVisitor visitor) => visitor.visitSwitchCase(this);
   /**
    * Return the expression controlling whether the statements will be executed.
@@ -8335,8 +9099,8 @@
    * Set the expression controlling whether the statements will be executed to the given expression.
    * @param expression the expression controlling whether the statements will be executed
    */
-  void set expression11(Expression expression) {
-    this._expression = becomeParentOf(expression);
+  void set expression(Expression expression11) {
+    this._expression = becomeParentOf(expression11);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     labels.accept(visitor);
@@ -8357,8 +9121,16 @@
    * @param colon the colon separating the keyword or the expression from the statements
    * @param statements the statements that will be executed if this switch member is selected
    */
-  SwitchDefault(List<Label> labels, Token keyword, Token colon, List<Statement> statements) : super(labels, keyword, colon, statements) {
+  SwitchDefault.full(List<Label> labels, Token keyword, Token colon, List<Statement> statements) : super.full(labels, keyword, colon, statements) {
   }
+  /**
+   * Initialize a newly created switch default.
+   * @param labels the labels associated with the switch member
+   * @param keyword the token representing the 'case' or 'default' keyword
+   * @param colon the colon separating the keyword or the expression from the statements
+   * @param statements the statements that will be executed if this switch member is selected
+   */
+  SwitchDefault({List<Label> labels, Token keyword, Token colon, List<Statement> statements}) : this.full(labels, keyword, colon, statements);
   accept(ASTVisitor visitor) => visitor.visitSwitchDefault(this);
   void visitChildren(ASTVisitor<Object> visitor) {
     labels.accept(visitor);
@@ -8398,7 +9170,7 @@
    * @param colon the colon separating the keyword or the expression from the statements
    * @param statements the statements that will be executed if this switch member is selected
    */
-  SwitchMember(List<Label> labels, Token keyword, Token colon, List<Statement> statements) {
+  SwitchMember.full(List<Label> labels, Token keyword, Token colon, List<Statement> statements) {
     this._labels = new NodeList<Label>(this);
     this._statements = new NodeList<Statement>(this);
     this._labels.addAll(labels);
@@ -8406,6 +9178,14 @@
     this._colon = colon;
     this._statements.addAll(statements);
   }
+  /**
+   * Initialize a newly created switch member.
+   * @param labels the labels associated with the switch member
+   * @param keyword the token representing the 'case' or 'default' keyword
+   * @param colon the colon separating the keyword or the expression from the statements
+   * @param statements the statements that will be executed if this switch member is selected
+   */
+  SwitchMember({List<Label> labels, Token keyword, Token colon, List<Statement> statements}) : this.full(labels, keyword, colon, statements);
   Token get beginToken {
     if (!_labels.isEmpty) {
       return _labels.beginToken;
@@ -8442,15 +9222,15 @@
    * Set the colon separating the keyword or the expression from the statements to the given token.
    * @param colon the colon separating the keyword or the expression from the statements
    */
-  void set colon4(Token colon) {
-    this._colon = colon;
+  void set colon(Token colon4) {
+    this._colon = colon4;
   }
   /**
    * Set the token representing the 'case' or 'default' keyword to the given token.
    * @param keyword the token representing the 'case' or 'default' keyword
    */
-  void set keyword19(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword18) {
+    this._keyword = keyword18;
   }
 }
 /**
@@ -8499,7 +9279,7 @@
    * @param members the switch members that can be selected by the expression
    * @param rightBracket the right curly bracket
    */
-  SwitchStatement(Token keyword, Token leftParenthesis, Expression expression, Token rightParenthesis, Token leftBracket, List<SwitchMember> members, Token rightBracket) {
+  SwitchStatement.full(Token keyword, Token leftParenthesis, Expression expression, Token rightParenthesis, Token leftBracket, List<SwitchMember> members, Token rightBracket) {
     this._members = new NodeList<SwitchMember>(this);
     this._keyword = keyword;
     this._leftParenthesis = leftParenthesis;
@@ -8509,6 +9289,17 @@
     this._members.addAll(members);
     this._rightBracket = rightBracket;
   }
+  /**
+   * Initialize a newly created switch statement.
+   * @param keyword the token representing the 'switch' keyword
+   * @param leftParenthesis the left parenthesis
+   * @param expression the expression used to determine which of the switch members will be selected
+   * @param rightParenthesis the right parenthesis
+   * @param leftBracket the left curly bracket
+   * @param members the switch members that can be selected by the expression
+   * @param rightBracket the right curly bracket
+   */
+  SwitchStatement({Token keyword, Token leftParenthesis, Expression expression, Token rightParenthesis, Token leftBracket, List<SwitchMember> members, Token rightBracket}) : this.full(keyword, leftParenthesis, expression, rightParenthesis, leftBracket, members, rightBracket);
   accept(ASTVisitor visitor) => visitor.visitSwitchStatement(this);
   Token get beginToken => _keyword;
   Token get endToken => _rightBracket;
@@ -8552,43 +9343,43 @@
    * expression.
    * @param expression the expression used to determine which of the switch members will be selected
    */
-  void set expression12(Expression expression) {
-    this._expression = becomeParentOf(expression);
+  void set expression(Expression expression12) {
+    this._expression = becomeParentOf(expression12);
   }
   /**
    * Set the token representing the 'switch' keyword to the given token.
    * @param keyword the token representing the 'switch' keyword
    */
-  void set keyword20(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword19) {
+    this._keyword = keyword19;
   }
   /**
    * Set the left curly bracket to the given token.
    * @param leftBracket the left curly bracket
    */
-  void set leftBracket8(Token leftBracket) {
-    this._leftBracket = leftBracket;
+  void set leftBracket(Token leftBracket7) {
+    this._leftBracket = leftBracket7;
   }
   /**
    * Set the left parenthesis to the given token.
    * @param leftParenthesis the left parenthesis
    */
-  void set leftParenthesis11(Token leftParenthesis) {
-    this._leftParenthesis = leftParenthesis;
+  void set leftParenthesis(Token leftParenthesis6) {
+    this._leftParenthesis = leftParenthesis6;
   }
   /**
    * Set the right curly bracket to the given token.
    * @param rightBracket the right curly bracket
    */
-  void set rightBracket8(Token rightBracket) {
-    this._rightBracket = rightBracket;
+  void set rightBracket(Token rightBracket7) {
+    this._rightBracket = rightBracket7;
   }
   /**
    * Set the right parenthesis to the given token.
    * @param rightParenthesis the right parenthesis
    */
-  void set rightParenthesis11(Token rightParenthesis) {
-    this._rightParenthesis = rightParenthesis;
+  void set rightParenthesis(Token rightParenthesis6) {
+    this._rightParenthesis = rightParenthesis6;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_expression, visitor);
@@ -8611,9 +9402,14 @@
    * Initialize a newly created this expression.
    * @param keyword the token representing the keyword
    */
-  ThisExpression(Token keyword) {
+  ThisExpression.full(Token keyword) {
     this._keyword = keyword;
   }
+  /**
+   * Initialize a newly created this expression.
+   * @param keyword the token representing the keyword
+   */
+  ThisExpression({Token keyword}) : this.full(keyword);
   accept(ASTVisitor visitor) => visitor.visitThisExpression(this);
   Token get beginToken => _keyword;
   Token get endToken => _keyword;
@@ -8626,8 +9422,8 @@
    * Set the token representing the keyword to the given token.
    * @param keyword the token representing the keyword
    */
-  void set keyword21(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword20) {
+    this._keyword = keyword20;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
   }
@@ -8655,10 +9451,16 @@
    * @param keyword the token representing the 'throw' keyword
    * @param expression the expression computing the exception to be thrown
    */
-  ThrowExpression(Token keyword, Expression expression) {
+  ThrowExpression.full(Token keyword, Expression expression) {
     this._keyword = keyword;
     this._expression = becomeParentOf(expression);
   }
+  /**
+   * Initialize a newly created throw expression.
+   * @param keyword the token representing the 'throw' keyword
+   * @param expression the expression computing the exception to be thrown
+   */
+  ThrowExpression({Token keyword, Expression expression}) : this.full(keyword, expression);
   accept(ASTVisitor visitor) => visitor.visitThrowExpression(this);
   Token get beginToken => _keyword;
   Token get endToken {
@@ -8683,15 +9485,15 @@
    * Set the expression computing the exception to be thrown to the given expression.
    * @param expression the expression computing the exception to be thrown
    */
-  void set expression13(Expression expression) {
-    this._expression = becomeParentOf(expression);
+  void set expression(Expression expression13) {
+    this._expression = becomeParentOf(expression13);
   }
   /**
    * Set the token representing the 'throw' keyword to the given token.
    * @param keyword the token representing the 'throw' keyword
    */
-  void set keyword22(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword21) {
+    this._keyword = keyword21;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_expression, visitor);
@@ -8722,10 +9524,18 @@
    * @param variableList the top-level variables being declared
    * @param semicolon the semicolon terminating the declaration
    */
-  TopLevelVariableDeclaration(Comment comment, List<Annotation> metadata, VariableDeclarationList variableList, Token semicolon) : super(comment, metadata) {
+  TopLevelVariableDeclaration.full(Comment comment, List<Annotation> metadata, VariableDeclarationList variableList, Token semicolon) : super.full(comment, metadata) {
     this._variableList = becomeParentOf(variableList);
     this._semicolon = semicolon;
   }
+  /**
+   * Initialize a newly created top-level variable declaration.
+   * @param comment the documentation comment associated with this variable
+   * @param metadata the annotations associated with this variable
+   * @param variableList the top-level variables being declared
+   * @param semicolon the semicolon terminating the declaration
+   */
+  TopLevelVariableDeclaration({Comment comment, List<Annotation> metadata, VariableDeclarationList variableList, Token semicolon}) : this.full(comment, metadata, variableList, semicolon);
   accept(ASTVisitor visitor) => visitor.visitTopLevelVariableDeclaration(this);
   Token get endToken => _semicolon;
   /**
@@ -8742,14 +9552,14 @@
    * Set the semicolon terminating the declaration to the given token.
    * @param semicolon the semicolon terminating the declaration
    */
-  void set semicolon16(Token semicolon) {
-    this._semicolon = semicolon;
+  void set semicolon(Token semicolon16) {
+    this._semicolon = semicolon16;
   }
   /**
    * Set the top-level variables being declared to the given list of variables.
    * @param variableList the top-level variables being declared
    */
-  void set variables3(VariableDeclarationList variableList) {
+  void set variables(VariableDeclarationList variableList) {
     variableList = becomeParentOf(variableList);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -8797,7 +9607,7 @@
    * @param finallyKeyword the token representing the 'finally' keyword
    * @param finallyClause the finally clause contained in the try statement
    */
-  TryStatement(Token tryKeyword, Block body, List<CatchClause> catchClauses, Token finallyKeyword, Block finallyClause) {
+  TryStatement.full(Token tryKeyword, Block body, List<CatchClause> catchClauses, Token finallyKeyword, Block finallyClause) {
     this._catchClauses = new NodeList<CatchClause>(this);
     this._tryKeyword = tryKeyword;
     this._body = becomeParentOf(body);
@@ -8805,6 +9615,15 @@
     this._finallyKeyword = finallyKeyword;
     this._finallyClause = becomeParentOf(finallyClause);
   }
+  /**
+   * Initialize a newly created try statement.
+   * @param tryKeyword the token representing the 'try' keyword
+   * @param body the body of the statement
+   * @param catchClauses the catch clauses contained in the try statement
+   * @param finallyKeyword the token representing the 'finally' keyword
+   * @param finallyClause the finally clause contained in the try statement
+   */
+  TryStatement({Token tryKeyword, Block body, List<CatchClause> catchClauses, Token finallyKeyword, Block finallyClause}) : this.full(tryKeyword, body, catchClauses, finallyKeyword, finallyClause);
   accept(ASTVisitor visitor) => visitor.visitTryStatement(this);
   Token get beginToken => _tryKeyword;
   /**
@@ -8848,29 +9667,29 @@
    * Set the body of the statement to the given block.
    * @param block the body of the statement
    */
-  void set body9(Block block) {
+  void set body(Block block) {
     _body = becomeParentOf(block);
   }
   /**
    * Set the finally clause contained in the try statement to the given block.
    * @param block the finally clause contained in the try statement
    */
-  void set finallyClause2(Block block) {
+  void set finallyClause(Block block) {
     _finallyClause = becomeParentOf(block);
   }
   /**
    * Set the token representing the 'finally' keyword to the given token.
    * @param finallyKeyword the token representing the 'finally' keyword
    */
-  void set finallyKeyword2(Token finallyKeyword) {
-    this._finallyKeyword = finallyKeyword;
+  void set finallyKeyword(Token finallyKeyword2) {
+    this._finallyKeyword = finallyKeyword2;
   }
   /**
    * Set the token representing the 'try' keyword to the given token.
    * @param tryKeyword the token representing the 'try' keyword
    */
-  void set tryKeyword2(Token tryKeyword) {
-    this._tryKeyword = tryKeyword;
+  void set tryKeyword(Token tryKeyword2) {
+    this._tryKeyword = tryKeyword2;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_body, visitor);
@@ -8904,10 +9723,18 @@
    * @param keyword the token representing the 'typedef' keyword
    * @param semicolon the semicolon terminating the declaration
    */
-  TypeAlias(Comment comment, List<Annotation> metadata, Token keyword, Token semicolon) : super(comment, metadata) {
+  TypeAlias.full(Comment comment, List<Annotation> metadata, Token keyword, Token semicolon) : super.full(comment, metadata) {
     this._keyword = keyword;
     this._semicolon = semicolon;
   }
+  /**
+   * Initialize a newly created type alias.
+   * @param comment the documentation comment associated with this type alias
+   * @param metadata the annotations associated with this type alias
+   * @param keyword the token representing the 'typedef' keyword
+   * @param semicolon the semicolon terminating the declaration
+   */
+  TypeAlias({Comment comment, List<Annotation> metadata, Token keyword, Token semicolon}) : this.full(comment, metadata, keyword, semicolon);
   Token get endToken => _semicolon;
   /**
    * Return the token representing the 'typedef' keyword.
@@ -8923,15 +9750,15 @@
    * Set the token representing the 'typedef' keyword to the given token.
    * @param keyword the token representing the 'typedef' keyword
    */
-  void set keyword23(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword22) {
+    this._keyword = keyword22;
   }
   /**
    * Set the semicolon terminating the declaration to the given token.
    * @param semicolon the semicolon terminating the declaration
    */
-  void set semicolon17(Token semicolon) {
-    this._semicolon = semicolon;
+  void set semicolon(Token semicolon17) {
+    this._semicolon = semicolon17;
   }
   Token get firstTokenAfterCommentAndMetadata => _keyword;
 }
@@ -8961,12 +9788,19 @@
    * @param arguments the type arguments associated with the type
    * @param rightBracket the right bracket
    */
-  TypeArgumentList(Token leftBracket, List<TypeName> arguments, Token rightBracket) {
+  TypeArgumentList.full(Token leftBracket, List<TypeName> arguments, Token rightBracket) {
     this._arguments = new NodeList<TypeName>(this);
     this._leftBracket = leftBracket;
     this._arguments.addAll(arguments);
     this._rightBracket = rightBracket;
   }
+  /**
+   * Initialize a newly created list of type arguments.
+   * @param leftBracket the left bracket
+   * @param arguments the type arguments associated with the type
+   * @param rightBracket the right bracket
+   */
+  TypeArgumentList({Token leftBracket, List<TypeName> arguments, Token rightBracket}) : this.full(leftBracket, arguments, rightBracket);
   accept(ASTVisitor visitor) => visitor.visitTypeArgumentList(this);
   /**
    * Return the type arguments associated with the type.
@@ -8989,15 +9823,15 @@
    * Set the left bracket to the given token.
    * @param leftBracket the left bracket
    */
-  void set leftBracket9(Token leftBracket) {
-    this._leftBracket = leftBracket;
+  void set leftBracket(Token leftBracket8) {
+    this._leftBracket = leftBracket8;
   }
   /**
    * Set the right bracket to the given token.
    * @param rightBracket the right bracket
    */
-  void set rightBracket9(Token rightBracket) {
-    this._rightBracket = rightBracket;
+  void set rightBracket(Token rightBracket8) {
+    this._rightBracket = rightBracket8;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     _arguments.accept(visitor);
@@ -9029,10 +9863,17 @@
    * @param typeArguments the type arguments associated with the type, or {@code null} if there are
    * no type arguments
    */
-  TypeName(Identifier name, TypeArgumentList typeArguments) {
+  TypeName.full(Identifier name, TypeArgumentList typeArguments) {
     this._name = becomeParentOf(name);
     this._typeArguments = becomeParentOf(typeArguments);
   }
+  /**
+   * Initialize a newly created type name.
+   * @param name the name of the type
+   * @param typeArguments the type arguments associated with the type, or {@code null} if there are
+   * no type arguments
+   */
+  TypeName({Identifier name, TypeArgumentList typeArguments}) : this.full(name, typeArguments);
   accept(ASTVisitor visitor) => visitor.visitTypeName(this);
   Token get beginToken => _name.beginToken;
   Token get endToken {
@@ -9062,22 +9903,22 @@
    * Set the name of the type to the given identifier.
    * @param identifier the name of the type
    */
-  void set name12(Identifier identifier) {
+  void set name(Identifier identifier) {
     _name = becomeParentOf(identifier);
   }
   /**
    * Set the type being named to the given type.
    * @param type the type being named
    */
-  void set type7(Type2 type) {
-    this._type = type;
+  void set type(Type2 type3) {
+    this._type = type3;
   }
   /**
    * Set the type arguments associated with the type to the given type arguments.
    * @param typeArguments the type arguments associated with the type
    */
-  void set typeArguments2(TypeArgumentList typeArguments) {
-    this._typeArguments = becomeParentOf(typeArguments);
+  void set typeArguments(TypeArgumentList typeArguments2) {
+    this._typeArguments = becomeParentOf(typeArguments2);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_name, visitor);
@@ -9113,11 +9954,20 @@
    * @param keyword the token representing the 'extends' keyword
    * @param bound the name of the upper bound for legal arguments
    */
-  TypeParameter(Comment comment, List<Annotation> metadata, SimpleIdentifier name, Token keyword, TypeName bound) : super(comment, metadata) {
+  TypeParameter.full(Comment comment, List<Annotation> metadata, SimpleIdentifier name, Token keyword, TypeName bound) : super.full(comment, metadata) {
     this._name = becomeParentOf(name);
     this._keyword = keyword;
     this._bound = becomeParentOf(bound);
   }
+  /**
+   * Initialize a newly created type parameter.
+   * @param comment the documentation comment associated with the type parameter
+   * @param metadata the annotations associated with the type parameter
+   * @param name the name of the type parameter
+   * @param keyword the token representing the 'extends' keyword
+   * @param bound the name of the upper bound for legal arguments
+   */
+  TypeParameter({Comment comment, List<Annotation> metadata, SimpleIdentifier name, Token keyword, TypeName bound}) : this.full(comment, metadata, name, keyword, bound);
   accept(ASTVisitor visitor) => visitor.visitTypeParameter(this);
   /**
    * Return the name of the upper bound for legal arguments, or {@code null} if there was no
@@ -9145,21 +9995,21 @@
    * Set the name of the upper bound for legal arguments to the given type name.
    * @param typeName the name of the upper bound for legal arguments
    */
-  void set bound2(TypeName typeName) {
+  void set bound(TypeName typeName) {
     _bound = becomeParentOf(typeName);
   }
   /**
    * Set the token representing the 'assert' keyword to the given token.
    * @param keyword the token representing the 'assert' keyword
    */
-  void set keyword24(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword23) {
+    this._keyword = keyword23;
   }
   /**
    * Set the name of the type parameter to the given identifier.
    * @param identifier the name of the type parameter
    */
-  void set name13(SimpleIdentifier identifier) {
+  void set name(SimpleIdentifier identifier) {
     _name = becomeParentOf(identifier);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -9195,12 +10045,19 @@
    * @param typeParameters the type parameters in the list
    * @param rightBracket the right angle bracket
    */
-  TypeParameterList(Token leftBracket, List<TypeParameter> typeParameters, Token rightBracket) {
+  TypeParameterList.full(Token leftBracket, List<TypeParameter> typeParameters, Token rightBracket) {
     this._typeParameters = new NodeList<TypeParameter>(this);
     this._leftBracket = leftBracket;
     this._typeParameters.addAll(typeParameters);
     this._rightBracket = rightBracket;
   }
+  /**
+   * Initialize a newly created list of type parameters.
+   * @param leftBracket the left angle bracket
+   * @param typeParameters the type parameters in the list
+   * @param rightBracket the right angle bracket
+   */
+  TypeParameterList({Token leftBracket, List<TypeParameter> typeParameters, Token rightBracket}) : this.full(leftBracket, typeParameters, rightBracket);
   accept(ASTVisitor visitor) => visitor.visitTypeParameterList(this);
   Token get beginToken => _leftBracket;
   Token get endToken => _rightBracket;
@@ -9246,11 +10103,18 @@
    * @param typeArguments the type argument associated with this literal, or {@code null} if no type
    * arguments were declared
    */
-  TypedLiteral(Token modifier, TypeArgumentList typeArguments) {
+  TypedLiteral.full(Token modifier, TypeArgumentList typeArguments) {
     this._modifier = modifier;
     this._typeArguments = becomeParentOf(typeArguments);
   }
   /**
+   * Initialize a newly created typed literal.
+   * @param modifier the const modifier associated with this literal
+   * @param typeArguments the type argument associated with this literal, or {@code null} if no type
+   * arguments were declared
+   */
+  TypedLiteral({Token modifier, TypeArgumentList typeArguments}) : this.full(modifier, typeArguments);
+  /**
    * Return the const modifier associated with this literal.
    * @return the const modifier associated with this literal
    */
@@ -9265,21 +10129,65 @@
    * Set the modifiers associated with this literal to the given modifiers.
    * @param modifiers the modifiers associated with this literal
    */
-  void set modifier2(Token modifier) {
-    this._modifier = modifier;
+  void set modifier(Token modifier2) {
+    this._modifier = modifier2;
   }
   /**
    * Set the type argument associated with this literal to the given arguments.
    * @param typeArguments the type argument associated with this literal
    */
-  void set typeArguments3(TypeArgumentList typeArguments) {
-    this._typeArguments = typeArguments;
+  void set typeArguments(TypeArgumentList typeArguments3) {
+    this._typeArguments = typeArguments3;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_typeArguments, visitor);
   }
 }
 /**
+ * The abstract class {@code UriBasedDirective} defines the behavior common to nodes that represent
+ * a directive that references a URI.
+ * <pre>
+ * uriBasedDirective ::={@link ExportDirective exportDirective}| {@link ImportDirective importDirective}| {@link PartDirective partDirective}</pre>
+ */
+abstract class UriBasedDirective extends Directive {
+  /**
+   * The URI referenced by this directive.
+   */
+  StringLiteral _uri;
+  /**
+   * Initialize a newly create URI-based directive.
+   * @param comment the documentation comment associated with this directive
+   * @param metadata the annotations associated with the directive
+   * @param uri the URI referenced by this directive
+   */
+  UriBasedDirective.full(Comment comment, List<Annotation> metadata, StringLiteral uri) : super.full(comment, metadata) {
+    this._uri = becomeParentOf(uri);
+  }
+  /**
+   * Initialize a newly create URI-based directive.
+   * @param comment the documentation comment associated with this directive
+   * @param metadata the annotations associated with the directive
+   * @param uri the URI referenced by this directive
+   */
+  UriBasedDirective({Comment comment, List<Annotation> metadata, StringLiteral uri}) : this.full(comment, metadata, uri);
+  /**
+   * Return the URI referenced by this directive.
+   * @return the URI referenced by this directive
+   */
+  StringLiteral get uri => _uri;
+  /**
+   * Set the URI referenced by this directive to the given URI.
+   * @param uri the URI referenced by this directive
+   */
+  void set uri(StringLiteral uri2) {
+    this._uri = becomeParentOf(uri2);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_uri, visitor);
+  }
+}
+/**
  * Instances of the class {@code VariableDeclaration} represent an identifier that has an initial
  * value associated with it. Instances of this class are always children of the class{@link VariableDeclarationList}.
  * <pre>
@@ -9309,18 +10217,27 @@
    * @param equals the equal sign separating the variable name from the initial value
    * @param initializer the expression used to compute the initial value for the variable
    */
-  VariableDeclaration(Comment comment, List<Annotation> metadata, SimpleIdentifier name, Token equals, Expression initializer) : super(comment, metadata) {
+  VariableDeclaration.full(Comment comment, List<Annotation> metadata, SimpleIdentifier name, Token equals, Expression initializer) : super.full(comment, metadata) {
     this._name = becomeParentOf(name);
     this._equals = equals;
     this._initializer = becomeParentOf(initializer);
   }
+  /**
+   * Initialize a newly created variable declaration.
+   * @param comment the documentation comment associated with this declaration
+   * @param metadata the annotations associated with this member
+   * @param name the name of the variable being declared
+   * @param equals the equal sign separating the variable name from the initial value
+   * @param initializer the expression used to compute the initial value for the variable
+   */
+  VariableDeclaration({Comment comment, List<Annotation> metadata, SimpleIdentifier name, Token equals, Expression initializer}) : this.full(comment, metadata, name, equals, initializer);
   accept(ASTVisitor visitor) => visitor.visitVariableDeclaration(this);
   /**
    * Return the {@link VariableElement} associated with this variable, or {@code null} if the AST
    * structure has not been resolved.
    * @return the {@link VariableElement} associated with this variable
    */
-  VariableElement get element => _name != null ? _name.element as VariableElement : null;
+  VariableElement get element => _name != null ? (_name.element as VariableElement) : null;
   Token get endToken {
     if (_initializer != null) {
       return _initializer.endToken;
@@ -9348,22 +10265,22 @@
    * Set the equal sign separating the variable name from the initial value to the given token.
    * @param equals the equal sign separating the variable name from the initial value
    */
-  void set equals6(Token equals) {
-    this._equals = equals;
+  void set equals(Token equals6) {
+    this._equals = equals6;
   }
   /**
    * Set the expression used to compute the initial value for the variable to the given expression.
    * @param initializer the expression used to compute the initial value for the variable
    */
-  void set initializer2(Expression initializer) {
-    this._initializer = becomeParentOf(initializer);
+  void set initializer(Expression initializer2) {
+    this._initializer = becomeParentOf(initializer2);
   }
   /**
    * Set the name of the variable being declared to the given identifier.
    * @param name the name of the variable being declared
    */
-  void set name14(SimpleIdentifier name) {
-    this._name = becomeParentOf(name);
+  void set name(SimpleIdentifier name7) {
+    this._name = becomeParentOf(name7);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     super.visitChildren(visitor);
@@ -9404,12 +10321,19 @@
    * @param type the type of the variables being declared
    * @param variables a list containing the individual variables being declared
    */
-  VariableDeclarationList(Token keyword, TypeName type, List<VariableDeclaration> variables) {
+  VariableDeclarationList.full(Token keyword, TypeName type, List<VariableDeclaration> variables) {
     this._variables = new NodeList<VariableDeclaration>(this);
     this._keyword = keyword;
     this._type = becomeParentOf(type);
     this._variables.addAll(variables);
   }
+  /**
+   * Initialize a newly created variable declaration list.
+   * @param keyword the token representing the 'final', 'const' or 'var' keyword
+   * @param type the type of the variables being declared
+   * @param variables a list containing the individual variables being declared
+   */
+  VariableDeclarationList({Token keyword, TypeName type, List<VariableDeclaration> variables}) : this.full(keyword, type, variables);
   accept(ASTVisitor visitor) => visitor.visitVariableDeclarationList(this);
   Token get beginToken {
     if (_keyword != null) {
@@ -9440,14 +10364,14 @@
    * Set the token representing the 'final', 'const' or 'var' keyword to the given token.
    * @param keyword the token representing the 'final', 'const' or 'var' keyword
    */
-  void set keyword25(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword24) {
+    this._keyword = keyword24;
   }
   /**
    * Set the type of the variables being declared to the given type name.
    * @param typeName the type of the variables being declared
    */
-  void set type8(TypeName typeName) {
+  void set type(TypeName typeName) {
     _type = becomeParentOf(typeName);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
@@ -9476,10 +10400,16 @@
    * @param variableList the fields being declared
    * @param semicolon the semicolon terminating the statement
    */
-  VariableDeclarationStatement(VariableDeclarationList variableList, Token semicolon) {
+  VariableDeclarationStatement.full(VariableDeclarationList variableList, Token semicolon) {
     this._variableList = becomeParentOf(variableList);
     this._semicolon = semicolon;
   }
+  /**
+   * Initialize a newly created variable declaration statement.
+   * @param variableList the fields being declared
+   * @param semicolon the semicolon terminating the statement
+   */
+  VariableDeclarationStatement({VariableDeclarationList variableList, Token semicolon}) : this.full(variableList, semicolon);
   accept(ASTVisitor visitor) => visitor.visitVariableDeclarationStatement(this);
   Token get beginToken => _variableList.beginToken;
   Token get endToken => _semicolon;
@@ -9497,15 +10427,15 @@
    * Set the semicolon terminating the statement to the given token.
    * @param semicolon the semicolon terminating the statement
    */
-  void set semicolon18(Token semicolon) {
-    this._semicolon = semicolon;
+  void set semicolon(Token semicolon18) {
+    this._semicolon = semicolon18;
   }
   /**
    * Set the variables being declared to the given list of variables.
    * @param variableList the variables being declared
    */
-  void set variables4(VariableDeclarationList variableList) {
-    this._variableList = becomeParentOf(variableList);
+  void set variables(VariableDeclarationList variableList2) {
+    this._variableList = becomeParentOf(variableList2);
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_variableList, visitor);
@@ -9546,13 +10476,22 @@
    * @param rightParenthesis the right parenthesis
    * @param body the body of the loop
    */
-  WhileStatement(Token keyword, Token leftParenthesis, Expression condition, Token rightParenthesis, Statement body) {
+  WhileStatement.full(Token keyword, Token leftParenthesis, Expression condition, Token rightParenthesis, Statement body) {
     this._keyword = keyword;
     this._leftParenthesis = leftParenthesis;
     this._condition = becomeParentOf(condition);
     this._rightParenthesis = rightParenthesis;
     this._body = becomeParentOf(body);
   }
+  /**
+   * Initialize a newly created while statement.
+   * @param keyword the token representing the 'while' keyword
+   * @param leftParenthesis the left parenthesis
+   * @param condition the expression used to determine whether to execute the body of the loop
+   * @param rightParenthesis the right parenthesis
+   * @param body the body of the loop
+   */
+  WhileStatement({Token keyword, Token leftParenthesis, Expression condition, Token rightParenthesis, Statement body}) : this.full(keyword, leftParenthesis, condition, rightParenthesis, body);
   accept(ASTVisitor visitor) => visitor.visitWhileStatement(this);
   Token get beginToken => _keyword;
   /**
@@ -9585,7 +10524,7 @@
    * Set the body of the loop to the given statement.
    * @param statement the body of the loop
    */
-  void set body10(Statement statement) {
+  void set body(Statement statement) {
     _body = becomeParentOf(statement);
   }
   /**
@@ -9593,29 +10532,29 @@
    * expression.
    * @param expression the expression used to determine whether to execute the body of the loop
    */
-  void set condition7(Expression expression) {
+  void set condition(Expression expression) {
     _condition = becomeParentOf(expression);
   }
   /**
    * Set the token representing the 'while' keyword to the given token.
    * @param keyword the token representing the 'while' keyword
    */
-  void set keyword26(Token keyword) {
-    this._keyword = keyword;
+  void set keyword(Token keyword25) {
+    this._keyword = keyword25;
   }
   /**
    * Set the left parenthesis to the given token.
    * @param leftParenthesis the left parenthesis
    */
-  void set leftParenthesis12(Token leftParenthesis) {
-    this._leftParenthesis = leftParenthesis;
+  void set leftParenthesis(Token leftParenthesis7) {
+    this._leftParenthesis = leftParenthesis7;
   }
   /**
    * Set the right parenthesis to the given token.
    * @param rightParenthesis the right parenthesis
    */
-  void set rightParenthesis12(Token rightParenthesis) {
-    this._rightParenthesis = rightParenthesis;
+  void set rightParenthesis(Token rightParenthesis7) {
+    this._rightParenthesis = rightParenthesis7;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     safelyVisitChild(_condition, visitor);
@@ -9643,11 +10582,17 @@
    * @param withKeyword the token representing the 'with' keyword
    * @param mixinTypes the names of the mixins that were specified
    */
-  WithClause(Token withKeyword, List<TypeName> mixinTypes) {
+  WithClause.full(Token withKeyword, List<TypeName> mixinTypes) {
     this._mixinTypes = new NodeList<TypeName>(this);
     this._withKeyword = withKeyword;
     this._mixinTypes.addAll(mixinTypes);
   }
+  /**
+   * Initialize a newly created with clause.
+   * @param withKeyword the token representing the 'with' keyword
+   * @param mixinTypes the names of the mixins that were specified
+   */
+  WithClause({Token withKeyword, List<TypeName> mixinTypes}) : this.full(withKeyword, mixinTypes);
   accept(ASTVisitor visitor) => visitor.visitWithClause(this);
   Token get beginToken => _withKeyword;
   Token get endToken => _mixinTypes.endToken;
@@ -9665,8 +10610,8 @@
    * Set the token representing the 'with' keyword to the given token.
    * @param withKeyword the token representing the 'with' keyword
    */
-  void set mixinKeyword(Token withKeyword) {
-    this._withKeyword = withKeyword;
+  void set mixinKeyword(Token withKeyword2) {
+    this._withKeyword = withKeyword2;
   }
   void visitChildren(ASTVisitor<Object> visitor) {
     _mixinTypes.accept(visitor);
@@ -9713,7 +10658,7 @@
     StringBuffer builder = new StringBuffer();
     for (StringLiteral string in node.strings) {
       Object value = string.accept(this);
-      if (value == ConstantEvaluator.NOT_A_CONSTANT) {
+      if (identical(value, NOT_A_CONSTANT)) {
         return value;
       }
       builder.add(value);
@@ -9721,121 +10666,121 @@
     return builder.toString();
   }
   Object visitBinaryExpression(BinaryExpression node) {
-    Object leftOperand3 = node.leftOperand.accept(this);
-    if (leftOperand3 == ConstantEvaluator.NOT_A_CONSTANT) {
-      return leftOperand3;
+    Object leftOperand2 = node.leftOperand.accept(this);
+    if (identical(leftOperand2, NOT_A_CONSTANT)) {
+      return leftOperand2;
     }
-    Object rightOperand3 = node.rightOperand.accept(this);
-    if (rightOperand3 == ConstantEvaluator.NOT_A_CONSTANT) {
-      return rightOperand3;
+    Object rightOperand2 = node.rightOperand.accept(this);
+    if (identical(rightOperand2, NOT_A_CONSTANT)) {
+      return rightOperand2;
     }
     if (node.operator.type == TokenType.AMPERSAND) {
-      if (leftOperand3 is int && rightOperand3 is int) {
-        return (leftOperand3 as int) & rightOperand3 as int;
+      if (leftOperand2 is int && rightOperand2 is int) {
+        return ((leftOperand2 as int)) & (rightOperand2 as int);
       }
     } else if (node.operator.type == TokenType.AMPERSAND_AMPERSAND) {
-      if (leftOperand3 is bool && rightOperand3 is bool) {
-        return (leftOperand3 as bool) && (rightOperand3 as bool);
+      if (leftOperand2 is bool && rightOperand2 is bool) {
+        return ((leftOperand2 as bool)) && ((rightOperand2 as bool));
       }
     } else if (node.operator.type == TokenType.BANG_EQ) {
-      if (leftOperand3 is bool && rightOperand3 is bool) {
-        return (leftOperand3 as bool) != (rightOperand3 as bool);
-      } else if (leftOperand3 is int && rightOperand3 is int) {
-        return (leftOperand3 as int) != rightOperand3;
-      } else if (leftOperand3 is double && rightOperand3 is double) {
-        return (leftOperand3 as double) != rightOperand3;
-      } else if (leftOperand3 is String && rightOperand3 is String) {
-        return (leftOperand3 as String) != rightOperand3;
+      if (leftOperand2 is bool && rightOperand2 is bool) {
+        return ((leftOperand2 as bool)) != ((rightOperand2 as bool));
+      } else if (leftOperand2 is int && rightOperand2 is int) {
+        return ((leftOperand2 as int)) != rightOperand2;
+      } else if (leftOperand2 is double && rightOperand2 is double) {
+        return ((leftOperand2 as double)) != rightOperand2;
+      } else if (leftOperand2 is String && rightOperand2 is String) {
+        return ((leftOperand2 as String)) != rightOperand2;
       }
     } else if (node.operator.type == TokenType.BAR) {
-      if (leftOperand3 is int && rightOperand3 is int) {
-        return (leftOperand3 as int) | rightOperand3 as int;
+      if (leftOperand2 is int && rightOperand2 is int) {
+        return ((leftOperand2 as int)) | (rightOperand2 as int);
       }
     } else if (node.operator.type == TokenType.BAR_BAR) {
-      if (leftOperand3 is bool && rightOperand3 is bool) {
-        return (leftOperand3 as bool) || (rightOperand3 as bool);
+      if (leftOperand2 is bool && rightOperand2 is bool) {
+        return ((leftOperand2 as bool)) || ((rightOperand2 as bool));
       }
     } else if (node.operator.type == TokenType.CARET) {
-      if (leftOperand3 is int && rightOperand3 is int) {
-        return (leftOperand3 as int) ^ rightOperand3 as int;
+      if (leftOperand2 is int && rightOperand2 is int) {
+        return ((leftOperand2 as int)) ^ (rightOperand2 as int);
       }
     } else if (node.operator.type == TokenType.EQ_EQ) {
-      if (leftOperand3 is bool && rightOperand3 is bool) {
-        return (leftOperand3 as bool) == (rightOperand3 as bool);
-      } else if (leftOperand3 is int && rightOperand3 is int) {
-        return (leftOperand3 as int) == rightOperand3;
-      } else if (leftOperand3 is double && rightOperand3 is double) {
-        return (leftOperand3 as double) == rightOperand3;
-      } else if (leftOperand3 is String && rightOperand3 is String) {
-        return (leftOperand3 as String) == rightOperand3;
+      if (leftOperand2 is bool && rightOperand2 is bool) {
+        return identical(((leftOperand2 as bool)), ((rightOperand2 as bool)));
+      } else if (leftOperand2 is int && rightOperand2 is int) {
+        return ((leftOperand2 as int)) == rightOperand2;
+      } else if (leftOperand2 is double && rightOperand2 is double) {
+        return ((leftOperand2 as double)) == rightOperand2;
+      } else if (leftOperand2 is String && rightOperand2 is String) {
+        return ((leftOperand2 as String)) == rightOperand2;
       }
     } else if (node.operator.type == TokenType.GT) {
-      if (leftOperand3 is int && rightOperand3 is int) {
-        return (leftOperand3 as int).compareTo(rightOperand3 as int) > 0;
-      } else if (leftOperand3 is double && rightOperand3 is double) {
-        return (leftOperand3 as double).compareTo(rightOperand3 as double) > 0;
+      if (leftOperand2 is int && rightOperand2 is int) {
+        return ((leftOperand2 as int)).compareTo((rightOperand2 as int)) > 0;
+      } else if (leftOperand2 is double && rightOperand2 is double) {
+        return ((leftOperand2 as double)).compareTo((rightOperand2 as double)) > 0;
       }
     } else if (node.operator.type == TokenType.GT_EQ) {
-      if (leftOperand3 is int && rightOperand3 is int) {
-        return (leftOperand3 as int).compareTo(rightOperand3 as int) >= 0;
-      } else if (leftOperand3 is double && rightOperand3 is double) {
-        return (leftOperand3 as double).compareTo(rightOperand3 as double) >= 0;
+      if (leftOperand2 is int && rightOperand2 is int) {
+        return ((leftOperand2 as int)).compareTo((rightOperand2 as int)) >= 0;
+      } else if (leftOperand2 is double && rightOperand2 is double) {
+        return ((leftOperand2 as double)).compareTo((rightOperand2 as double)) >= 0;
       }
     } else if (node.operator.type == TokenType.GT_GT) {
-      if (leftOperand3 is int && rightOperand3 is int) {
-        return (leftOperand3 as int) >> (rightOperand3 as int);
+      if (leftOperand2 is int && rightOperand2 is int) {
+        return ((leftOperand2 as int)) >> ((rightOperand2 as int));
       }
     } else if (node.operator.type == TokenType.LT) {
-      if (leftOperand3 is int && rightOperand3 is int) {
-        return (leftOperand3 as int).compareTo(rightOperand3 as int) < 0;
-      } else if (leftOperand3 is double && rightOperand3 is double) {
-        return (leftOperand3 as double).compareTo(rightOperand3 as double) < 0;
+      if (leftOperand2 is int && rightOperand2 is int) {
+        return ((leftOperand2 as int)).compareTo((rightOperand2 as int)) < 0;
+      } else if (leftOperand2 is double && rightOperand2 is double) {
+        return ((leftOperand2 as double)).compareTo((rightOperand2 as double)) < 0;
       }
     } else if (node.operator.type == TokenType.LT_EQ) {
-      if (leftOperand3 is int && rightOperand3 is int) {
-        return (leftOperand3 as int).compareTo(rightOperand3 as int) <= 0;
-      } else if (leftOperand3 is double && rightOperand3 is double) {
-        return (leftOperand3 as double).compareTo(rightOperand3 as double) <= 0;
+      if (leftOperand2 is int && rightOperand2 is int) {
+        return ((leftOperand2 as int)).compareTo((rightOperand2 as int)) <= 0;
+      } else if (leftOperand2 is double && rightOperand2 is double) {
+        return ((leftOperand2 as double)).compareTo((rightOperand2 as double)) <= 0;
       }
     } else if (node.operator.type == TokenType.LT_LT) {
-      if (leftOperand3 is int && rightOperand3 is int) {
-        return (leftOperand3 as int) << (rightOperand3 as int);
+      if (leftOperand2 is int && rightOperand2 is int) {
+        return ((leftOperand2 as int)) << ((rightOperand2 as int));
       }
     } else if (node.operator.type == TokenType.MINUS) {
-      if (leftOperand3 is int && rightOperand3 is int) {
-        return (leftOperand3 as int) - rightOperand3 as int;
-      } else if (leftOperand3 is double && rightOperand3 is double) {
-        return (leftOperand3 as double) - (rightOperand3 as double);
+      if (leftOperand2 is int && rightOperand2 is int) {
+        return ((leftOperand2 as int)) - (rightOperand2 as int);
+      } else if (leftOperand2 is double && rightOperand2 is double) {
+        return ((leftOperand2 as double)) - ((rightOperand2 as double));
       }
     } else if (node.operator.type == TokenType.PERCENT) {
-      if (leftOperand3 is int && rightOperand3 is int) {
-        return (leftOperand3 as int).remainder(rightOperand3 as int);
-      } else if (leftOperand3 is double && rightOperand3 is double) {
-        return (leftOperand3 as double) % (rightOperand3 as double);
+      if (leftOperand2 is int && rightOperand2 is int) {
+        return ((leftOperand2 as int)).remainder((rightOperand2 as int));
+      } else if (leftOperand2 is double && rightOperand2 is double) {
+        return ((leftOperand2 as double)) % ((rightOperand2 as double));
       }
     } else if (node.operator.type == TokenType.PLUS) {
-      if (leftOperand3 is int && rightOperand3 is int) {
-        return (leftOperand3 as int) + rightOperand3 as int;
-      } else if (leftOperand3 is double && rightOperand3 is double) {
-        return (leftOperand3 as double) + (rightOperand3 as double);
+      if (leftOperand2 is int && rightOperand2 is int) {
+        return ((leftOperand2 as int)) + (rightOperand2 as int);
+      } else if (leftOperand2 is double && rightOperand2 is double) {
+        return ((leftOperand2 as double)) + ((rightOperand2 as double));
       }
     } else if (node.operator.type == TokenType.STAR) {
-      if (leftOperand3 is int && rightOperand3 is int) {
-        return (leftOperand3 as int) * rightOperand3 as int;
-      } else if (leftOperand3 is double && rightOperand3 is double) {
-        return (leftOperand3 as double) * (rightOperand3 as double);
+      if (leftOperand2 is int && rightOperand2 is int) {
+        return ((leftOperand2 as int)) * (rightOperand2 as int);
+      } else if (leftOperand2 is double && rightOperand2 is double) {
+        return ((leftOperand2 as double)) * ((rightOperand2 as double));
       }
     } else if (node.operator.type == TokenType.SLASH) {
-      if (leftOperand3 is int && rightOperand3 is int) {
-        return (leftOperand3 as int) / rightOperand3 as int;
-      } else if (leftOperand3 is double && rightOperand3 is double) {
-        return (leftOperand3 as double) / (rightOperand3 as double);
+      if (leftOperand2 is int && rightOperand2 is int) {
+        return ((leftOperand2 as int)) ~/ (rightOperand2 as int);
+      } else if (leftOperand2 is double && rightOperand2 is double) {
+        return ((leftOperand2 as double)) / ((rightOperand2 as double));
       }
     } else if (node.operator.type == TokenType.TILDE_SLASH) {
-      if (leftOperand3 is int && rightOperand3 is int) {
-        return (leftOperand3 as int) / rightOperand3 as int;
-      } else if (leftOperand3 is double && rightOperand3 is double) {
-        return (leftOperand3 as double) ~/ (rightOperand3 as double);
+      if (leftOperand2 is int && rightOperand2 is int) {
+        return ((leftOperand2 as int)) ~/ (rightOperand2 as int);
+      } else if (leftOperand2 is double && rightOperand2 is double) {
+        return ((leftOperand2 as double)) ~/ ((rightOperand2 as double));
       }
     }
     return visitExpression(node);
@@ -9855,7 +10800,7 @@
     List<Object> list = new List<Object>();
     for (Expression element in node.elements) {
       Object value = element.accept(this);
-      if (value == ConstantEvaluator.NOT_A_CONSTANT) {
+      if (identical(value, NOT_A_CONSTANT)) {
         return value;
       }
       list.add(value);
@@ -9865,12 +10810,12 @@
   Object visitMapLiteral(MapLiteral node) {
     Map<String, Object> map = new Map<String, Object>();
     for (MapLiteralEntry entry in node.entries) {
-      Object key3 = entry.key.accept(this);
-      Object value10 = entry.value.accept(this);
-      if (key3 is! String || value10 == ConstantEvaluator.NOT_A_CONSTANT) {
+      Object key2 = entry.key.accept(this);
+      Object value7 = entry.value.accept(this);
+      if (key2 is! String || identical(value7, NOT_A_CONSTANT)) {
         return NOT_A_CONSTANT;
       }
-      map[key3 as String] = value10;
+      map[(key2 as String)] = value7;
     }
     return map;
   }
@@ -9880,27 +10825,27 @@
   Object visitParenthesizedExpression(ParenthesizedExpression node) => node.expression.accept(this);
   Object visitPrefixedIdentifier(PrefixedIdentifier node) => getConstantValue(null);
   Object visitPrefixExpression(PrefixExpression node) {
-    Object operand4 = node.operand.accept(this);
-    if (operand4 == ConstantEvaluator.NOT_A_CONSTANT) {
-      return operand4;
+    Object operand2 = node.operand.accept(this);
+    if (identical(operand2, NOT_A_CONSTANT)) {
+      return operand2;
     }
     if (node.operator.type == TokenType.BANG) {
-      if (operand4 == true) {
+      if (identical(operand2, true)) {
         return false;
-      } else if (operand4 == false) {
+      } else if (identical(operand2, false)) {
         return true;
       }
     } else if (node.operator.type == TokenType.TILDE) {
-      if (operand4 is int) {
-        return ~(operand4 as int);
+      if (operand2 is int) {
+        return ~((operand2 as int));
       }
     } else if (node.operator.type == TokenType.MINUS) {
-      if (operand4 == null) {
+      if (operand2 == null) {
         return null;
-      } else if (operand4 is int) {
-        return -(operand4 as int);
-      } else if (operand4 is double) {
-        return -(operand4 as double);
+      } else if (operand2 is int) {
+        return -((operand2 as int));
+      } else if (operand2 is double) {
+        return -((operand2 as double));
       }
     }
     return NOT_A_CONSTANT;
@@ -9912,7 +10857,7 @@
     StringBuffer builder = new StringBuffer();
     for (InterpolationElement element in node.elements) {
       Object value = element.accept(this);
-      if (value == ConstantEvaluator.NOT_A_CONSTANT) {
+      if (identical(value, NOT_A_CONSTANT)) {
         return value;
       }
       builder.add(value);
@@ -9926,7 +10871,7 @@
    */
   Object getConstantValue(Element element) {
     if (element is FieldElement) {
-      FieldElement field = element as FieldElement;
+      FieldElement field = (element as FieldElement);
       if (field.isStatic() && field.isConst()) {
       }
     }
@@ -10026,7 +10971,7 @@
   R visitMethodDeclaration(MethodDeclaration node) => visitClassMember(node);
   R visitMethodInvocation(MethodInvocation node) => visitNode(node);
   R visitNamedExpression(NamedExpression node) => visitExpression(node);
-  R visitNamespaceDirective(NamespaceDirective node) => visitDirective(node);
+  R visitNamespaceDirective(NamespaceDirective node) => visitUriBasedDirective(node);
   R visitNode(ASTNode node) {
     node.visitChildren(this);
     return null;
@@ -10034,7 +10979,7 @@
   R visitNormalFormalParameter(NormalFormalParameter node) => visitFormalParameter(node);
   R visitNullLiteral(NullLiteral node) => visitLiteral(node);
   R visitParenthesizedExpression(ParenthesizedExpression node) => visitExpression(node);
-  R visitPartDirective(PartDirective node) => visitDirective(node);
+  R visitPartDirective(PartDirective node) => visitUriBasedDirective(node);
   R visitPartOfDirective(PartOfDirective node) => visitDirective(node);
   R visitPostfixExpression(PostfixExpression node) => visitExpression(node);
   R visitPrefixedIdentifier(PrefixedIdentifier node) => visitIdentifier(node);
@@ -10066,6 +11011,7 @@
   R visitTypeName(TypeName node) => visitNode(node);
   R visitTypeParameter(TypeParameter node) => visitNode(node);
   R visitTypeParameterList(TypeParameterList node) => visitNode(node);
+  R visitUriBasedDirective(UriBasedDirective node) => visitDirective(node);
   R visitVariableDeclaration(VariableDeclaration node) => visitDeclaration(node);
   R visitVariableDeclarationList(VariableDeclarationList node) => visitNode(node);
   R visitVariableDeclarationStatement(VariableDeclarationStatement node) => visitStatement(node);
@@ -10073,6 +11019,91 @@
   R visitWithClause(WithClause node) => visitNode(node);
 }
 /**
+ * Instances of the class {@code NodeLocator} locate the {@link ASTNode AST node} associated with a
+ * source range, given the AST structure built from the source. More specifically, they will return
+ * the {@link ASTNode AST node} with the shortest length whose source range completely encompasses
+ * the specified range.
+ */
+class NodeLocator extends GeneralizingASTVisitor<Object> {
+  /**
+   * The start offset of the range used to identify the node.
+   */
+  int _startOffset = 0;
+  /**
+   * The end offset of the range used to identify the node.
+   */
+  int _endOffset = 0;
+  /**
+   * The element that was found that corresponds to the given source range, or {@code null} if there
+   * is no such element.
+   */
+  ASTNode _foundNode;
+  /**
+   * Initialize a newly created locator to locate one or more {@link ASTNode AST nodes} by locating
+   * the node within an AST structure that corresponds to the given offset in the source.
+   * @param offset the offset used to identify the node
+   */
+  NodeLocator.con1(int offset) {
+    _jtd_constructor_114_impl(offset);
+  }
+  _jtd_constructor_114_impl(int offset) {
+    _jtd_constructor_115_impl(offset, offset);
+  }
+  /**
+   * Initialize a newly created locator to locate one or more {@link ASTNode AST nodes} by locating
+   * the node within an AST structure that corresponds to the given range of characters in the
+   * source.
+   * @param start the start offset of the range used to identify the node
+   * @param end the end offset of the range used to identify the node
+   */
+  NodeLocator.con2(int start, int end) {
+    _jtd_constructor_115_impl(start, end);
+  }
+  _jtd_constructor_115_impl(int start, int end) {
+    this._startOffset = start;
+    this._endOffset = end;
+  }
+  /**
+   * Return the node that was found that corresponds to the given source range, or {@code null} if
+   * there is no such node.
+   * @return the node that was found
+   */
+  ASTNode get foundNode => _foundNode;
+  /**
+   * Search within the given AST node for an identifier representing a {@link DartElement Dart
+   * element} in the specified source range. Return the element that was found, or {@code null} if
+   * no element was found.
+   * @param node the AST node within which to search
+   * @return the element that was found
+   */
+  ASTNode searchWithin(ASTNode node) {
+    try {
+      node.accept(this);
+    } on NodeLocator_NodeFoundException catch (exception) {
+    } on JavaException catch (exception) {
+      AnalysisEngine.instance.logger.logInformation2("Unable to locate element at offset (${_startOffset} - ${_endOffset})", exception);
+      return null;
+    }
+    return _foundNode;
+  }
+  Object visitNode(ASTNode node) {
+    try {
+      node.visitChildren(this);
+    } on NodeLocator_NodeFoundException catch (exception) {
+      throw exception;
+    } on JavaException catch (exception) {
+      AnalysisEngine.instance.logger.logInformation2("Exception caught while traversing an AST structure.", exception);
+    }
+    int start = node.offset;
+    int end = start + node.length;
+    if (start <= _startOffset && _endOffset <= end) {
+      _foundNode = node;
+      throw new NodeLocator_NodeFoundException();
+    }
+    return null;
+  }
+}
+/**
  * Instances of the class {@code NodeFoundException} are used to cancel visiting after a node has
  * been found.
  */
@@ -10726,12 +11757,12 @@
   Object visitComment(Comment node) => null;
   Object visitCommentReference(CommentReference node) => null;
   Object visitCompilationUnit(CompilationUnit node) {
-    ScriptTag scriptTag4 = node.scriptTag;
+    ScriptTag scriptTag6 = node.scriptTag;
     NodeList<Directive> directives2 = node.directives;
-    visit(scriptTag4);
-    String prefix = scriptTag4 == null ? "" : " ";
+    visit(scriptTag6);
+    String prefix = scriptTag6 == null ? "" : " ";
     visitList4(prefix, directives2, " ");
-    prefix = scriptTag4 == null && directives2.isEmpty ? "" : " ";
+    prefix = scriptTag6 == null && directives2.isEmpty ? "" : " ";
     visitList4(prefix, node.declarations, " ");
     return null;
   }
@@ -10804,7 +11835,7 @@
   }
   Object visitExportDirective(ExportDirective node) {
     _writer.print("export ");
-    visit(node.libraryUri);
+    visit(node.uri);
     visitList4(" ", node.combinators, " ");
     _writer.print(';');
     return null;
@@ -10860,7 +11891,7 @@
         _writer.print(", ");
       }
       if (groupEnd == null && parameter is DefaultFormalParameter) {
-        if (parameter.kind == ParameterKind.NAMED) {
+        if (identical(parameter.kind, ParameterKind.NAMED)) {
           groupEnd = "}";
           _writer.print('{');
         } else {
@@ -10950,7 +11981,7 @@
   }
   Object visitImportDirective(ImportDirective node) {
     _writer.print("import ");
-    visit(node.libraryUri);
+    visit(node.uri);
     visit3(" as ", node.prefix);
     visitList4(" ", node.combinators, " ");
     _writer.print(';');
@@ -11090,7 +12121,7 @@
   }
   Object visitPartDirective(PartDirective node) {
     _writer.print("part ");
-    visit(node.partUri);
+    visit(node.uri);
     _writer.print(';');
     return null;
   }
diff --git a/pkg/analyzer-experimental/lib/src/generated/element.dart b/pkg/analyzer-experimental/lib/src/generated/element.dart
index 2a4af3f..407dd69 100644
--- a/pkg/analyzer-experimental/lib/src/generated/element.dart
+++ b/pkg/analyzer-experimental/lib/src/generated/element.dart
@@ -9,7 +9,8 @@
 import 'source.dart';
 import 'scanner.dart' show Keyword;
 import 'ast.dart';
-import 'package:analyzer-experimental/src/generated/utilities_dart.dart';
+import 'engine.dart' show AnalysisContext;
+import 'utilities_dart.dart';
 
 /**
  * The interface {@code Annotation} defines the behavior of objects representing a single annotation
@@ -28,18 +29,23 @@
  */
 abstract class ClassElement implements Element {
   /**
-   * Return an array containing all of the accessors (getters and setters) contained in this class.
-   * @return the accessors contained in this class
+   * Return an array containing all of the accessors (getters and setters) declared in this class.
+   * @return the accessors declared in this class
    */
   List<PropertyAccessorElement> get accessors;
   /**
-   * Return an array containing all of the constructors contained in this class.
-   * @return the constructors contained in this class
+   * Return an array containing all the supertypes defined for this class and its supertypes.
+   * @return all the supertypes of this class, including mixins
+   */
+  List<InterfaceType> get allSupertypes;
+  /**
+   * Return an array containing all of the constructors declared in this class.
+   * @return the constructors declared in this class
    */
   List<ConstructorElement> get constructors;
   /**
-   * Return an array containing all of the fields contained in this class.
-   * @return the fields contained in this class
+   * Return an array containing all of the fields declared in this class.
+   * @return the fields declared in this class
    */
   List<FieldElement> get fields;
   /**
@@ -48,8 +54,8 @@
    */
   List<InterfaceType> get interfaces;
   /**
-   * Return an array containing all of the methods contained in this class.
-   * @return the methods contained in this class
+   * Return an array containing all of the methods declared in this class.
+   * @return the methods declared in this class
    */
   List<MethodElement> get methods;
   /**
@@ -59,6 +65,13 @@
    */
   List<InterfaceType> get mixins;
   /**
+   * Return the named constructor declared in this class with the given name, or {@code null} if
+   * this class does not declare a named constructor with the given name.
+   * @param name the name of the constructor to be returned
+   * @return the element representing the specified constructor
+   */
+  ConstructorElement getNamedConstructor(String name);
+  /**
    * Return the superclass of this class, or {@code null} if the class represents the class
    * 'Object'. All other classes will have a non-{@code null} superclass. If the superclass was not
    * explicitly declared then the implicit superclass 'Object' will be returned.
@@ -71,16 +84,83 @@
    */
   InterfaceType get type;
   /**
-   * Return an array containing all of the type variables defined for this class.
-   * @return the type variables defined for this class
+   * Return an array containing all of the type variables declared for this class.
+   * @return the type variables declared for this class
    */
   List<TypeVariableElement> get typeVariables;
   /**
+   * Return the unnamed constructor declared in this class, or {@code null} if this class does not
+   * declare an unnamed constructor but does declare named constructors. The returned constructor
+   * will be synthetic if this class does not declare any constructors, in which case it will
+   * represent the default constructor for the class.
+   * @return the unnamed constructor defined in this class
+   */
+  ConstructorElement get unnamedConstructor;
+  /**
    * Return {@code true} if this class is abstract. A class is abstract if it has an explicit{@code abstract} modifier. Note, that this definition of <i>abstract</i> is different from
    * <i>has unimplemented members</i>.
    * @return {@code true} if this class is abstract
    */
   bool isAbstract();
+  /**
+   * Return the element representing the getter that results from looking up the given getter in
+   * this class with respect to the given library, or {@code null} if the look up fails. The
+   * behavior of this method is defined by the Dart Language Specification in section 12.15.1:
+   * <blockquote> The result of looking up getter (respectively setter) <i>m</i> in class <i>C</i>
+   * with respect to library <i>L</i> is:
+   * <ul>
+   * <li>If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
+   * accessible to <i>L</i>, then that getter (respectively setter) is the result of the lookup.
+   * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the result
+   * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect to <i>L</i>.
+   * Otherwise, we say that the lookup has failed.</li>
+   * </ul>
+   * </blockquote>
+   * @param getterName the name of the getter being looked up
+   * @param library the library with respect to which the lookup is being performed
+   * @return the result of looking up the given getter in this class with respect to the given
+   * library
+   */
+  PropertyAccessorElement lookUpGetter(String getterName, LibraryElement library);
+  /**
+   * Return the element representing the method that results from looking up the given method in
+   * this class with respect to the given library, or {@code null} if the look up fails. The
+   * behavior of this method is defined by the Dart Language Specification in section 12.15.1:
+   * <blockquote> The result of looking up method <i>m</i> in class <i>C</i> with respect to library
+   * <i>L</i> is:
+   * <ul>
+   * <li>If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then
+   * that method is the result of the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then
+   * the result of the lookup is the result of looking up method <i>m</i> in <i>S</i> with respect
+   * to <i>L</i>. Otherwise, we say that the lookup has failed.</li>
+   * </ul>
+   * </blockquote>
+   * @param methodName the name of the method being looked up
+   * @param library the library with respect to which the lookup is being performed
+   * @return the result of looking up the given method in this class with respect to the given
+   * library
+   */
+  MethodElement lookUpMethod(String methodName, LibraryElement library);
+  /**
+   * Return the element representing the setter that results from looking up the given setter in
+   * this class with respect to the given library, or {@code null} if the look up fails. The
+   * behavior of this method is defined by the Dart Language Specification in section 12.16:
+   * <blockquote> The result of looking up getter (respectively setter) <i>m</i> in class <i>C</i>
+   * with respect to library <i>L</i> is:
+   * <ul>
+   * <li>If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
+   * accessible to <i>L</i>, then that getter (respectively setter) is the result of the lookup.
+   * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the result
+   * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect to <i>L</i>.
+   * Otherwise, we say that the lookup has failed.</li>
+   * </ul>
+   * </blockquote>
+   * @param setterName the name of the setter being looked up
+   * @param library the library with respect to which the lookup is being performed
+   * @return the result of looking up the given setter in this class with respect to the given
+   * library
+   */
+  PropertyAccessorElement lookUpSetter(String setterName, LibraryElement library);
 }
 /**
  * The interface {@code CompilationUnitElement} defines the behavior of elements representing a
@@ -99,21 +179,11 @@
    */
   LibraryElement get enclosingElement;
   /**
-   * Return an array containing all of the fields contained in this compilation unit.
-   * @return the fields contained in this compilation unit
-   */
-  List<FieldElement> get fields;
-  /**
    * Return an array containing all of the top-level functions contained in this compilation unit.
    * @return the top-level functions contained in this compilation unit
    */
   List<FunctionElement> get functions;
   /**
-   * Return the source that corresponds to this compilation unit.
-   * @return the source that corresponds to this compilation unit
-   */
-  Source get source;
-  /**
    * Return an array containing all of the type aliases contained in this compilation unit.
    * @return the type aliases contained in this compilation unit
    */
@@ -123,6 +193,11 @@
    * @return the classes contained in this compilation unit
    */
   List<ClassElement> get types;
+  /**
+   * Return an array containing all of the variables contained in this compilation unit.
+   * @return the variables contained in this compilation unit
+   */
+  List<VariableElement> get variables;
 }
 /**
  * The interface {@code ConstructorElement} defines the behavior of elements representing a
@@ -218,6 +293,21 @@
    */
   int get nameOffset;
   /**
+   * Return the source that contains this element, or {@code null} if this element is not contained
+   * in a source.
+   * @return the source that contains this element
+   */
+  Source get source;
+  /**
+   * Return {@code true} if this element, assuming that it is within scope, is accessible to code in
+   * the given library. This is defined by the Dart Language Specification in section 3.2:
+   * <blockquote> A declaration <i>m</i> is accessible to library <i>L</i> if <i>m</i> is declared
+   * in <i>L</i> or if <i>m</i> is public. </blockquote>
+   * @param library the library in which a possible reference to this element would occur
+   * @return {@code true} if this element is accessible to code in the given library
+   */
+  bool isAccessibleIn(LibraryElement library);
+  /**
    * Return {@code true} if this element is synthetic. A synthetic element is an element that is not
    * represented in the source code explicitly, but is implied by the source code, such as the
    * default constructor for a class that does not explicitly define any constructors.
@@ -362,6 +452,19 @@
  * The interface {@code FunctionElement} defines the behavior of elements representing a function.
  */
 abstract class FunctionElement implements ExecutableElement {
+  /**
+   * Return a source range that covers the approximate portion of the source in which the name of
+   * this function is visible, or {@code null} if there is no single range of characters within
+   * which the variable's name is visible.
+   * <ul>
+   * <li>For a local function, this includes everything from the beginning of the function's body to
+   * the end of the block that encloses the function declaration.</li>
+   * <li>For top-level functions, {@code null} will be returned because they are potentially visible
+   * in multiple sources.</li>
+   * </ul>
+   * @return the range of characters in which the name of this function is visible
+   */
+  SourceRange get visibleRange;
 }
 /**
  * The interface {@code HideCombinator} defines the behavior of combinators that cause some of the
@@ -386,11 +489,6 @@
    * @return the libraries referenced from script tags in the HTML file
    */
   List<LibraryElement> get libraries;
-  /**
-   * Return the source that corresponds to this HTML file.
-   * @return the source that corresponds to this HTML file
-   */
-  Source get source;
 }
 /**
  * The interface {@code ImportElement} defines the behavior of objects representing information
@@ -446,6 +544,11 @@
    */
   FunctionElement get entryPoint;
   /**
+   * Return an array containing all of the libraries that are exported from this library.
+   * @return an array containing all of the libraries that are exported from this library
+   */
+  List<LibraryElement> get exportedLibraries;
+  /**
    * Return an array containing all of the exports defined in this library.
    * @return the exports defined in this library
    */
@@ -474,6 +577,11 @@
    * @return the prefixes used to {@code import} libraries into this library
    */
   List<PrefixElement> get prefixes;
+  /**
+   * Answer {@code true} if this library is an application that can be run in the browser.
+   * @return {@code true} if this library is an application that can be run in the browser
+   */
+  bool isBrowserApplication();
 }
 /**
  * The interface {@code MethodElement} defines the behavior of elements that represent a method
@@ -533,6 +641,11 @@
    * @return the kind of this parameter
    */
   ParameterKind get parameterKind;
+  /**
+   * Return {@code true} if this parameter is an initializing formal parameter.
+   * @return {@code true} if this parameter is an initializing formal parameter
+   */
+  bool isInitializingFormal();
 }
 /**
  * The interface {@code PrefixElement} defines the behavior common to elements that represent a
@@ -664,6 +777,21 @@
    */
   Type2 get type;
   /**
+   * Return a source range that covers the approximate portion of the source in which the name of
+   * this variable is visible, or {@code null} if there is no single range of characters within
+   * which the variable's name is visible.
+   * <ul>
+   * <li>For a local variable, this includes everything from the end of the variable's initializer
+   * to the end of the block that encloses the variable declaration.</li>
+   * <li>For a parameter, this includes the body of the method or function that declares the
+   * parameter.</li>
+   * <li>For fields and top-level variables, {@code null} will be returned because they are
+   * potentially visible in multiple sources.</li>
+   * </ul>
+   * @return the range of characters in which the name of this variable is visible
+   */
+  SourceRange get visibleRange;
+  /**
    * Return {@code true} if this variable is a const variable. Variables are const if they have been
    * marked as being const using the {@code const} modifier.
    * @return {@code true} if this variable is a const variable
@@ -697,6 +825,7 @@
     this._element = element;
   }
   Element get element => _element;
+  String toString() => "@${_element.toString()}";
 }
 /**
  * Instances of the class {@code ClassElementImpl} implement a {@code ClassElement}.
@@ -750,30 +879,35 @@
   ClassElementImpl(Identifier name) : super.con1(name) {
   }
   List<PropertyAccessorElement> get accessors => _accessors;
-  ElementImpl getChild(String identifier) {
+  List<InterfaceType> get allSupertypes {
+    Collection<InterfaceType> list = new Set<InterfaceType>();
+    collectAllSupertypes(list);
+    return new List.from(list);
+  }
+  ElementImpl getChild(String identifier19) {
     for (PropertyAccessorElement accessor in _accessors) {
-      if ((accessor as PropertyAccessorElementImpl).identifier == identifier) {
-        return accessor as PropertyAccessorElementImpl;
+      if (((accessor as PropertyAccessorElementImpl)).identifier == identifier19) {
+        return (accessor as PropertyAccessorElementImpl);
       }
     }
     for (ConstructorElement constructor in _constructors) {
-      if ((constructor as ConstructorElementImpl).identifier == identifier) {
-        return constructor as ConstructorElementImpl;
+      if (((constructor as ConstructorElementImpl)).identifier == identifier19) {
+        return (constructor as ConstructorElementImpl);
       }
     }
     for (FieldElement field in _fields) {
-      if ((field as FieldElementImpl).identifier == identifier) {
-        return field as FieldElementImpl;
+      if (((field as FieldElementImpl)).identifier == identifier19) {
+        return (field as FieldElementImpl);
       }
     }
     for (MethodElement method in _methods) {
-      if ((method as MethodElementImpl).identifier == identifier) {
-        return method as MethodElementImpl;
+      if (((method as MethodElementImpl)).identifier == identifier19) {
+        return (method as MethodElementImpl);
       }
     }
     for (TypeVariableElement typeVariable in _typeVariables) {
-      if ((typeVariable as TypeVariableElementImpl).identifier == identifier) {
-        return typeVariable as TypeVariableElementImpl;
+      if (((typeVariable as TypeVariableElementImpl)).identifier == identifier19) {
+        return (typeVariable as TypeVariableElementImpl);
       }
     }
     return null;
@@ -784,10 +918,103 @@
   ElementKind get kind => ElementKind.CLASS;
   List<MethodElement> get methods => _methods;
   List<InterfaceType> get mixins => _mixins;
+  ConstructorElement getNamedConstructor(String name21) {
+    for (ConstructorElement element in constructors) {
+      String elementName = element.name;
+      if (elementName != null && elementName == name21) {
+        return element;
+      }
+    }
+    return null;
+  }
   InterfaceType get supertype => _supertype;
   InterfaceType get type => _type;
   List<TypeVariableElement> get typeVariables => _typeVariables;
+  ConstructorElement get unnamedConstructor {
+    for (ConstructorElement element in constructors) {
+      String name10 = element.name;
+      if (name10 == null || name10.isEmpty) {
+        return element;
+      }
+    }
+    return null;
+  }
   bool isAbstract() => hasModifier(Modifier.ABSTRACT);
+  PropertyAccessorElement lookUpGetter(String getterName, LibraryElement library) {
+    PropertyAccessorElement element = getGetter(getterName);
+    if (element != null && element.isAccessibleIn(library)) {
+      return element;
+    }
+    for (InterfaceType mixin in _mixins) {
+      ClassElement mixinElement = mixin.element;
+      if (mixinElement != null) {
+        element = ((mixinElement as ClassElementImpl)).getGetter(getterName);
+        if (element != null && element.isAccessibleIn(library)) {
+          return element;
+        }
+      }
+    }
+    if (_supertype != null) {
+      ClassElement supertypeElement = _supertype.element;
+      if (supertypeElement != null) {
+        element = supertypeElement.lookUpGetter(getterName, library);
+        if (element != null && element.isAccessibleIn(library)) {
+          return element;
+        }
+      }
+    }
+    return null;
+  }
+  MethodElement lookUpMethod(String methodName, LibraryElement library) {
+    MethodElement element = getMethod(methodName);
+    if (element != null && element.isAccessibleIn(library)) {
+      return element;
+    }
+    for (InterfaceType mixin in _mixins) {
+      ClassElement mixinElement = mixin.element;
+      if (mixinElement != null) {
+        element = ((mixinElement as ClassElementImpl)).getMethod(methodName);
+        if (element != null && element.isAccessibleIn(library)) {
+          return element;
+        }
+      }
+    }
+    if (_supertype != null) {
+      ClassElement supertypeElement = _supertype.element;
+      if (supertypeElement != null) {
+        element = supertypeElement.lookUpMethod(methodName, library);
+        if (element != null && element.isAccessibleIn(library)) {
+          return element;
+        }
+      }
+    }
+    return null;
+  }
+  PropertyAccessorElement lookUpSetter(String setterName, LibraryElement library) {
+    PropertyAccessorElement element = getSetter(setterName);
+    if (element != null && element.isAccessibleIn(library)) {
+      return element;
+    }
+    for (InterfaceType mixin in _mixins) {
+      ClassElement mixinElement = mixin.element;
+      if (mixinElement != null) {
+        element = ((mixinElement as ClassElementImpl)).getSetter(setterName);
+        if (element != null && element.isAccessibleIn(library)) {
+          return element;
+        }
+      }
+    }
+    if (_supertype != null) {
+      ClassElement supertypeElement = _supertype.element;
+      if (supertypeElement != null) {
+        element = supertypeElement.lookUpSetter(setterName, library);
+        if (element != null && element.isAccessibleIn(library)) {
+          return element;
+        }
+      }
+    }
+    return null;
+  }
   /**
    * Set whether this class is abstract to correspond to the given value.
    * @param isAbstract {@code true} if the class is abstract
@@ -799,84 +1026,159 @@
    * Set the accessors contained in this class to the given accessors.
    * @param accessors the accessors contained in this class
    */
-  void set accessors2(List<PropertyAccessorElement> accessors) {
-    for (PropertyAccessorElement accessor in accessors) {
-      (accessor as PropertyAccessorElementImpl).enclosingElement2 = this;
+  void set accessors(List<PropertyAccessorElement> accessors2) {
+    for (PropertyAccessorElement accessor in accessors2) {
+      ((accessor as PropertyAccessorElementImpl)).enclosingElement = this;
     }
-    this._accessors = accessors;
+    this._accessors = accessors2;
   }
   /**
    * Set the constructors contained in this class to the given constructors.
    * @param constructors the constructors contained in this class
    */
-  void set constructors2(List<ConstructorElement> constructors) {
-    for (ConstructorElement constructor in constructors) {
-      (constructor as ConstructorElementImpl).enclosingElement2 = this;
+  void set constructors(List<ConstructorElement> constructors2) {
+    for (ConstructorElement constructor in constructors2) {
+      ((constructor as ConstructorElementImpl)).enclosingElement = this;
     }
-    this._constructors = constructors;
+    this._constructors = constructors2;
   }
   /**
    * Set the fields contained in this class to the given fields.
    * @param fields the fields contained in this class
    */
-  void set fields3(List<FieldElement> fields) {
-    for (FieldElement field in fields) {
-      (field as FieldElementImpl).enclosingElement2 = this;
+  void set fields(List<FieldElement> fields2) {
+    for (FieldElement field in fields2) {
+      ((field as FieldElementImpl)).enclosingElement = this;
     }
-    this._fields = fields;
+    this._fields = fields2;
   }
   /**
    * Set the interfaces that are implemented by this class to the given types.
    * @param the interfaces that are implemented by this class
    */
-  void set interfaces2(List<InterfaceType> interfaces) {
-    this._interfaces = interfaces;
+  void set interfaces(List<InterfaceType> interfaces2) {
+    this._interfaces = interfaces2;
   }
   /**
    * Set the methods contained in this class to the given methods.
    * @param methods the methods contained in this class
    */
-  void set methods2(List<MethodElement> methods) {
-    for (MethodElement method in methods) {
-      (method as MethodElementImpl).enclosingElement2 = this;
+  void set methods(List<MethodElement> methods2) {
+    for (MethodElement method in methods2) {
+      ((method as MethodElementImpl)).enclosingElement = this;
     }
-    this._methods = methods;
+    this._methods = methods2;
   }
   /**
    * Set the mixins that are applied to the class being extended in order to derive the superclass
    * of this class to the given types.
    * @param mixins the mixins that are applied to derive the superclass of this class
    */
-  void set mixins2(List<InterfaceType> mixins) {
-    this._mixins = mixins;
+  void set mixins(List<InterfaceType> mixins2) {
+    this._mixins = mixins2;
   }
   /**
    * Set the superclass of the class to the given type.
    * @param supertype the superclass of the class
    */
-  void set supertype2(InterfaceType supertype) {
-    this._supertype = supertype;
+  void set supertype(InterfaceType supertype2) {
+    this._supertype = supertype2;
   }
   /**
    * Set the type defined by the class to the given type.
    * @param type the type defined by the class
    */
-  void set type9(InterfaceType type) {
-    this._type = type;
+  void set type(InterfaceType type4) {
+    this._type = type4;
   }
   /**
    * Set the type variables defined for this class to the given type variables.
    * @param typeVariables the type variables defined for this class
    */
-  void set typeVariables2(List<TypeVariableElement> typeVariables) {
-    for (TypeVariableElement typeVariable in typeVariables) {
-      (typeVariable as TypeVariableElementImpl).enclosingElement2 = this;
+  void set typeVariables(List<TypeVariableElement> typeVariables2) {
+    for (TypeVariableElement typeVariable in typeVariables2) {
+      ((typeVariable as TypeVariableElementImpl)).enclosingElement = this;
     }
-    this._typeVariables = typeVariables;
+    this._typeVariables = typeVariables2;
   }
-  String toString() {
-    String name15 = name;
-    return name15 == null ? "<unnamed class>" : "class ${name15}";
+  void appendTo(StringBuffer builder) {
+    String name11 = name;
+    if (name11 == null) {
+      builder.add("{unnamed class}");
+    } else {
+      builder.add(name11);
+    }
+    int variableCount = _typeVariables.length;
+    if (variableCount > 0) {
+      builder.add("<");
+      for (int i = 0; i < variableCount; i++) {
+        if (i > 0) {
+          builder.add(", ");
+        }
+        ((_typeVariables[i] as TypeVariableElementImpl)).appendTo(builder);
+      }
+      builder.add(">");
+    }
+  }
+  void collectAllSupertypes(Collection<InterfaceType> list) {
+    if (_supertype == null || list.contains(_supertype)) {
+      return;
+    }
+    list.add(_supertype);
+    ((_supertype.element as ClassElementImpl)).collectAllSupertypes(list);
+    for (InterfaceType type in interfaces) {
+      if (!list.contains(type)) {
+        list.add(type);
+        ((type.element as ClassElementImpl)).collectAllSupertypes(list);
+      }
+    }
+    for (InterfaceType type in mixins) {
+      if (!list.contains(type)) {
+        list.add(type);
+      }
+    }
+  }
+  /**
+   * Return the element representing the getter with the given name that is declared in this class,
+   * or {@code null} if this class does not declare a getter with the given name.
+   * @param getterName the name of the getter to be returned
+   * @return the getter declared in this class with the given name
+   */
+  PropertyAccessorElement getGetter(String getterName) {
+    for (PropertyAccessorElement accessor in _accessors) {
+      if (accessor.isGetter() && accessor.name == getterName) {
+        return accessor;
+      }
+    }
+    return null;
+  }
+  /**
+   * Return the element representing the method with the given name that is declared in this class,
+   * or {@code null} if this class does not declare a method with the given name.
+   * @param methodName the name of the method to be returned
+   * @return the method declared in this class with the given name
+   */
+  MethodElement getMethod(String methodName) {
+    for (MethodElement method in _methods) {
+      if (method.name == methodName) {
+        return method;
+      }
+    }
+    return null;
+  }
+  /**
+   * Return the element representing the setter with the given name that is declared in this class,
+   * or {@code null} if this class does not declare a setter with the given name.
+   * @param setterName the name of the getter to be returned
+   * @return the getter declared in this class with the given name
+   */
+  PropertyAccessorElement getSetter(String setterName) {
+    for (PropertyAccessorElement accessor in _accessors) {
+      if (accessor.isSetter() && accessor.name == setterName) {
+        return accessor;
+      }
+    }
+    return null;
   }
 }
 /**
@@ -889,14 +1191,14 @@
    */
   List<PropertyAccessorElement> _accessors = PropertyAccessorElementImpl.EMPTY_ARRAY;
   /**
-   * An array containing all of the fields contained in this compilation unit.
-   */
-  List<FieldElement> _fields = FieldElementImpl.EMPTY_ARRAY;
-  /**
    * An array containing all of the top-level functions contained in this compilation unit.
    */
   List<FunctionElement> _functions = FunctionElementImpl.EMPTY_ARRAY;
   /**
+   * An array containing all of the variables contained in this compilation unit.
+   */
+  List<VariableElement> _variables = VariableElementImpl.EMPTY_ARRAY;
+  /**
    * The source that corresponds to this compilation unit.
    */
   Source _source;
@@ -918,102 +1220,109 @@
    */
   CompilationUnitElementImpl(String name) : super.con2(name, -1) {
   }
-  bool operator ==(Object object) => this.runtimeType == object.runtimeType && _source == (object as CompilationUnitElementImpl).source;
+  bool operator ==(Object object) => identical(this.runtimeType, object.runtimeType) && _source == ((object as CompilationUnitElementImpl)).source;
   List<PropertyAccessorElement> get accessors => _accessors;
-  ElementImpl getChild(String identifier) {
+  ElementImpl getChild(String identifier20) {
     for (PropertyAccessorElement accessor in _accessors) {
-      if ((accessor as PropertyAccessorElementImpl).identifier == identifier) {
-        return accessor as PropertyAccessorElementImpl;
+      if (((accessor as PropertyAccessorElementImpl)).identifier == identifier20) {
+        return (accessor as PropertyAccessorElementImpl);
       }
     }
-    for (FieldElement field in _fields) {
-      if ((field as FieldElementImpl).identifier == identifier) {
-        return field as FieldElementImpl;
+    for (VariableElement variable in _variables) {
+      if (((variable as VariableElementImpl)).identifier == identifier20) {
+        return (variable as VariableElementImpl);
       }
     }
     for (ExecutableElement function in _functions) {
-      if ((function as ExecutableElementImpl).identifier == identifier) {
-        return function as ExecutableElementImpl;
+      if (((function as ExecutableElementImpl)).identifier == identifier20) {
+        return (function as ExecutableElementImpl);
       }
     }
     for (TypeAliasElement typeAlias in _typeAliases) {
-      if ((typeAlias as TypeAliasElementImpl).identifier == identifier) {
-        return typeAlias as TypeAliasElementImpl;
+      if (((typeAlias as TypeAliasElementImpl)).identifier == identifier20) {
+        return (typeAlias as TypeAliasElementImpl);
       }
     }
     for (ClassElement type in _types) {
-      if ((type as ClassElementImpl).identifier == identifier) {
-        return type as ClassElementImpl;
+      if (((type as ClassElementImpl)).identifier == identifier20) {
+        return (type as ClassElementImpl);
       }
     }
     return null;
   }
-  LibraryElement get enclosingElement => super.enclosingElement as LibraryElement;
-  List<FieldElement> get fields => _fields;
+  LibraryElement get enclosingElement => (super.enclosingElement as LibraryElement);
   List<FunctionElement> get functions => _functions;
   String get identifier => source.fullName;
   ElementKind get kind => ElementKind.COMPILATION_UNIT;
   Source get source => _source;
   List<TypeAliasElement> get typeAliases => _typeAliases;
   List<ClassElement> get types => _types;
+  List<VariableElement> get variables => _variables;
   int get hashCode => _source.hashCode;
   /**
    * Set the top-level accessors (getters and setters) contained in this compilation unit to the
    * given accessors.
    * @param the top-level accessors (getters and setters) contained in this compilation unit
    */
-  void set accessors3(List<PropertyAccessorElement> accessors) {
-    for (PropertyAccessorElement accessor in accessors) {
-      (accessor as PropertyAccessorElementImpl).enclosingElement2 = this;
+  void set accessors(List<PropertyAccessorElement> accessors3) {
+    for (PropertyAccessorElement accessor in accessors3) {
+      ((accessor as PropertyAccessorElementImpl)).enclosingElement = this;
     }
-    this._accessors = accessors;
-  }
-  /**
-   * Set the fields contained in this compilation unit to the given fields.
-   * @param fields the fields contained in this compilation unit
-   */
-  void set fields4(List<FieldElement> fields) {
-    for (FieldElement field in fields) {
-      (field as FieldElementImpl).enclosingElement2 = this;
-    }
-    this._fields = fields;
+    this._accessors = accessors3;
   }
   /**
    * Set the top-level functions contained in this compilation unit to the given functions.
    * @param functions the top-level functions contained in this compilation unit
    */
-  void set functions2(List<FunctionElement> functions) {
-    for (FunctionElement function in functions) {
-      (function as FunctionElementImpl).enclosingElement2 = this;
+  void set functions(List<FunctionElement> functions2) {
+    for (FunctionElement function in functions2) {
+      ((function as FunctionElementImpl)).enclosingElement = this;
     }
-    this._functions = functions;
+    this._functions = functions2;
   }
   /**
    * Set the source that corresponds to this compilation unit to the given source.
    * @param source the source that corresponds to this compilation unit
    */
-  void set source3(Source source) {
-    this._source = source;
+  void set source(Source source5) {
+    this._source = source5;
   }
   /**
    * Set the type aliases contained in this compilation unit to the given type aliases.
    * @param typeAliases the type aliases contained in this compilation unit
    */
-  void set typeAliases2(List<TypeAliasElement> typeAliases) {
-    for (TypeAliasElement typeAlias in typeAliases) {
-      (typeAlias as TypeAliasElementImpl).enclosingElement2 = this;
+  void set typeAliases(List<TypeAliasElement> typeAliases2) {
+    for (TypeAliasElement typeAlias in typeAliases2) {
+      ((typeAlias as TypeAliasElementImpl)).enclosingElement = this;
     }
-    this._typeAliases = typeAliases;
+    this._typeAliases = typeAliases2;
   }
   /**
    * Set the types contained in this compilation unit to the given types.
    * @param types types contained in this compilation unit
    */
-  void set types2(List<ClassElement> types) {
-    for (ClassElement type in types) {
-      (type as ClassElementImpl).enclosingElement2 = this;
+  void set types(List<ClassElement> types2) {
+    for (ClassElement type in types2) {
+      ((type as ClassElementImpl)).enclosingElement = this;
     }
-    this._types = types;
+    this._types = types2;
+  }
+  /**
+   * Set the variables contained in this compilation unit to the given variables.
+   * @param variables the variables contained in this compilation unit
+   */
+  void set variables(List<VariableElement> variables2) {
+    for (VariableElement field in variables2) {
+      ((field as VariableElementImpl)).enclosingElement = this;
+    }
+    this._variables = variables2;
+  }
+  void appendTo(StringBuffer builder) {
+    if (_source == null) {
+      builder.add("{compilation unit}");
+    } else {
+      builder.add(_source.fullName);
+    }
   }
 }
 /**
@@ -1030,7 +1339,7 @@
    */
   ConstructorElementImpl(Identifier name) : super.con1(name) {
   }
-  ClassElement get enclosingElement => super.enclosingElement as ClassElement;
+  ClassElement get enclosingElement => (super.enclosingElement as ClassElement);
   ElementKind get kind => ElementKind.CONSTRUCTOR;
   bool isConst() => hasModifier(Modifier.CONST);
   bool isFactory() => hasModifier(Modifier.FACTORY);
@@ -1041,6 +1350,15 @@
   void set factory(bool isFactory) {
     setModifier(Modifier.FACTORY, isFactory);
   }
+  void appendTo(StringBuffer builder) {
+    builder.add(enclosingElement.name);
+    String name12 = name;
+    if (name12 != null && !name12.isEmpty) {
+      builder.add(".");
+      builder.add(name12);
+    }
+    super.appendTo(builder);
+  }
 }
 /**
  * Instances of the class {@code DynamicElementImpl} represent the synthetic element representing
@@ -1048,13 +1366,18 @@
  */
 class DynamicElementImpl extends ElementImpl {
   /**
+   * Return the unique instance of this class.
+   * @return the unique instance of this class
+   */
+  static DynamicElementImpl get instance => (DynamicTypeImpl.instance.element as DynamicElementImpl);
+  /**
    * The type defined by this element.
    */
   DynamicTypeImpl _type;
   /**
    * Initialize a newly created instance of this class. Instances of this class should <b>not</b> be
    * created except as part of creating the type associated with this element. The single instance
-   * of this class should be accessed through the single instance of the class{@link DynamicTypeImpl}.
+   * of this class should be accessed through the method {@link #getInstance()}.
    */
   DynamicElementImpl() : super.con2(Keyword.DYNAMIC.syntax, -1) {
     setModifier(Modifier.SYNTHETIC, true);
@@ -1069,8 +1392,8 @@
    * Set the type defined by this element to the given type.
    * @param type the type defined by this element
    */
-  void set type10(DynamicTypeImpl type) {
-    this._type = type;
+  void set type(DynamicTypeImpl type5) {
+    this._type = type5;
   }
 }
 /**
@@ -1104,11 +1427,11 @@
    * Initialize a newly created element to have the given name.
    * @param name the name of this element
    */
-  ElementImpl.con1(Identifier name) {
-    _jtd_constructor_129_impl(name);
+  ElementImpl.con1(Identifier name22) {
+    _jtd_constructor_135_impl(name22);
   }
-  _jtd_constructor_129_impl(Identifier name) {
-    _jtd_constructor_130_impl(name == null ? "" : name.name, name == null ? -1 : name.offset);
+  _jtd_constructor_135_impl(Identifier name22) {
+    _jtd_constructor_136_impl(name22 == null ? "" : name22.name, name22 == null ? -1 : name22.offset);
   }
   /**
    * Initialize a newly created element to have the given name.
@@ -1116,21 +1439,21 @@
    * @param nameOffset the offset of the name of this element in the file that contains the
    * declaration of this element
    */
-  ElementImpl.con2(String name, int nameOffset) {
-    _jtd_constructor_130_impl(name, nameOffset);
+  ElementImpl.con2(String name8, int nameOffset2) {
+    _jtd_constructor_136_impl(name8, nameOffset2);
   }
-  _jtd_constructor_130_impl(String name, int nameOffset) {
-    this._name = name;
-    this._nameOffset = nameOffset;
+  _jtd_constructor_136_impl(String name8, int nameOffset2) {
+    this._name = name8;
+    this._nameOffset = nameOffset2;
     this._modifiers = new Set();
   }
-  bool operator ==(Object object) => object is Element && (object as Element).location == location;
+  bool operator ==(Object object) => object is Element && ((object as Element)).location == location;
   Element getAncestor(Type elementClass) {
     Element ancestor = _enclosingElement;
     while (ancestor != null && !isInstanceOf(ancestor, elementClass)) {
       ancestor = ancestor.enclosingElement;
     }
-    return ancestor as Element;
+    return (ancestor as Element);
   }
   /**
    * Return the child of this element that is uniquely identified by the given identifier, or{@code null} if there is no such child.
@@ -1150,14 +1473,26 @@
   List<Annotation> get metadata => _metadata;
   String get name => _name;
   int get nameOffset => _nameOffset;
+  Source get source {
+    if (_enclosingElement == null) {
+      return null;
+    }
+    return _enclosingElement.source;
+  }
   int get hashCode => location.hashCode;
+  bool isAccessibleIn(LibraryElement library18) {
+    if (Identifier.isPrivateName(_name)) {
+      return library18 == library;
+    }
+    return true;
+  }
   bool isSynthetic() => hasModifier(Modifier.SYNTHETIC);
   /**
    * Set the metadata associate with this element to the given array of annotations.
    * @param metadata the metadata to be associated with this element
    */
-  void set metadata2(List<Annotation> metadata) {
-    this._metadata = metadata;
+  void set metadata(List<Annotation> metadata2) {
+    this._metadata = metadata2;
   }
   /**
    * Set whether this element is synthetic to correspond to the given value.
@@ -1166,6 +1501,24 @@
   void set synthetic(bool isSynthetic) {
     setModifier(Modifier.SYNTHETIC, isSynthetic);
   }
+  String toString() {
+    StringBuffer builder = new StringBuffer();
+    appendTo(builder);
+    return builder.toString();
+  }
+  /**
+   * Append a textual representation of this type to the given builder.
+   * @param builder the builder to which the text is to be appended
+   */
+  void appendTo(StringBuffer builder) {
+    if (_name == null) {
+      builder.add("<unnamed ");
+      builder.add(runtimeType.toString());
+      builder.add(">");
+    } else {
+      builder.add(_name);
+    }
+  }
   /**
    * Return an identifier that uniquely identifies this element among the children of this element's
    * parent.
@@ -1182,7 +1535,7 @@
    * Set the enclosing element of this element to the given element.
    * @param element the enclosing element of this element
    */
-  void set enclosingElement2(ElementImpl element) {
+  void set enclosingElement(ElementImpl element) {
     _enclosingElement = element;
   }
   /**
@@ -1210,19 +1563,19 @@
   /**
    * The character used to separate components in the encoded form.
    */
-  static int _SEPARATOR_CHAR = 0x3b;
+  static int _SEPARATOR_CHAR = 0x3B;
   /**
    * Initialize a newly created location to represent the given element.
    * @param element the element whose location is being represented
    */
   ElementLocationImpl.con1(Element element) {
-    _jtd_constructor_131_impl(element);
+    _jtd_constructor_137_impl(element);
   }
-  _jtd_constructor_131_impl(Element element) {
+  _jtd_constructor_137_impl(Element element) {
     List<String> components = new List<String>();
     Element ancestor = element;
     while (ancestor != null) {
-      components.insertRange(0, 1, (ancestor as ElementImpl).identifier);
+      components.insertRange(0, 1, ((ancestor as ElementImpl)).identifier);
       ancestor = ancestor.enclosingElement;
     }
     this._components = new List.from(components);
@@ -1232,16 +1585,16 @@
    * @param encoding the encoded form of a location
    */
   ElementLocationImpl.con2(String encoding) {
-    _jtd_constructor_132_impl(encoding);
+    _jtd_constructor_138_impl(encoding);
   }
-  _jtd_constructor_132_impl(String encoding) {
+  _jtd_constructor_138_impl(String encoding) {
     this._components = decode(encoding);
   }
   bool operator ==(Object object) {
     if (object is! ElementLocationImpl) {
       return false;
     }
-    ElementLocationImpl location = object as ElementLocationImpl;
+    ElementLocationImpl location = (object as ElementLocationImpl);
     return JavaArrays.equals(_components, location._components);
   }
   /**
@@ -1254,13 +1607,14 @@
     int length2 = _components.length;
     for (int i = 0; i < length2; i++) {
       if (i > 0) {
-        builder.addCharCode(ElementLocationImpl._SEPARATOR_CHAR);
+        builder.addCharCode(_SEPARATOR_CHAR);
       }
       encode(builder, _components[i]);
     }
     return builder.toString();
   }
   int get hashCode => JavaArrays.makeHashCode(_components);
+  String toString() => encoding;
   /**
    * Decode the encoded form of a location into an array of components.
    * @param encoding the encoded form of a location
@@ -1272,10 +1626,10 @@
     int index = 0;
     int length3 = encoding.length;
     while (index < length3) {
-      int currentChar = encoding.charCodeAt(index);
-      if (currentChar == ElementLocationImpl._SEPARATOR_CHAR) {
-        if (index + 1 < length3 && encoding.charCodeAt(index + 1) == ElementLocationImpl._SEPARATOR_CHAR) {
-          builder.addCharCode(ElementLocationImpl._SEPARATOR_CHAR);
+      int currentChar = encoding.codeUnitAt(index);
+      if (currentChar == _SEPARATOR_CHAR) {
+        if (index + 1 < length3 && encoding.codeUnitAt(index + 1) == _SEPARATOR_CHAR) {
+          builder.addCharCode(_SEPARATOR_CHAR);
           index += 2;
         } else {
           components.add(builder.toString());
@@ -1300,9 +1654,9 @@
   void encode(StringBuffer builder, String component) {
     int length4 = component.length;
     for (int i = 0; i < length4; i++) {
-      int currentChar = component.charCodeAt(i);
-      if (currentChar == ElementLocationImpl._SEPARATOR_CHAR) {
-        builder.addCharCode(ElementLocationImpl._SEPARATOR_CHAR);
+      int currentChar = component.codeUnitAt(i);
+      if (currentChar == _SEPARATOR_CHAR) {
+        builder.addCharCode(_SEPARATOR_CHAR);
       }
       builder.addCharCode(currentChar);
     }
@@ -1341,9 +1695,9 @@
    * @param name the name of this element
    */
   ExecutableElementImpl.con1(Identifier name) : super.con1(name) {
-    _jtd_constructor_133_impl(name);
+    _jtd_constructor_139_impl(name);
   }
-  _jtd_constructor_133_impl(Identifier name) {
+  _jtd_constructor_139_impl(Identifier name) {
   }
   /**
    * Initialize a newly created executable element to have the given name.
@@ -1352,29 +1706,29 @@
    * declaration of this element
    */
   ExecutableElementImpl.con2(String name, int nameOffset) : super.con2(name, nameOffset) {
-    _jtd_constructor_134_impl(name, nameOffset);
+    _jtd_constructor_140_impl(name, nameOffset);
   }
-  _jtd_constructor_134_impl(String name, int nameOffset) {
+  _jtd_constructor_140_impl(String name, int nameOffset) {
   }
-  ElementImpl getChild(String identifier) {
+  ElementImpl getChild(String identifier21) {
     for (ExecutableElement function in _functions) {
-      if ((function as ExecutableElementImpl).identifier == identifier) {
-        return function as ExecutableElementImpl;
+      if (((function as ExecutableElementImpl)).identifier == identifier21) {
+        return (function as ExecutableElementImpl);
       }
     }
     for (LabelElement label in _labels) {
-      if ((label as LabelElementImpl).identifier == identifier) {
-        return label as LabelElementImpl;
+      if (((label as LabelElementImpl)).identifier == identifier21) {
+        return (label as LabelElementImpl);
       }
     }
     for (VariableElement variable in _localVariables) {
-      if ((variable as VariableElementImpl).identifier == identifier) {
-        return variable as VariableElementImpl;
+      if (((variable as VariableElementImpl)).identifier == identifier21) {
+        return (variable as VariableElementImpl);
       }
     }
     for (ParameterElement parameter in _parameters) {
-      if ((parameter as ParameterElementImpl).identifier == identifier) {
-        return parameter as ParameterElementImpl;
+      if (((parameter as ParameterElementImpl)).identifier == identifier21) {
+        return (parameter as ParameterElementImpl);
       }
     }
     return null;
@@ -1388,48 +1742,63 @@
    * Set the functions defined within this executable element to the given functions.
    * @param functions the functions defined within this executable element
    */
-  void set functions3(List<ExecutableElement> functions) {
-    for (ExecutableElement function in functions) {
-      (function as ExecutableElementImpl).enclosingElement2 = this;
+  void set functions(List<ExecutableElement> functions3) {
+    for (ExecutableElement function in functions3) {
+      ((function as ExecutableElementImpl)).enclosingElement = this;
     }
-    this._functions = functions;
+    this._functions = functions3;
   }
   /**
    * Set the labels defined within this executable element to the given labels.
    * @param labels the labels defined within this executable element
    */
-  void set labels2(List<LabelElement> labels) {
-    for (LabelElement label in labels) {
-      (label as LabelElementImpl).enclosingElement2 = this;
+  void set labels(List<LabelElement> labels2) {
+    for (LabelElement label in labels2) {
+      ((label as LabelElementImpl)).enclosingElement = this;
     }
-    this._labels = labels;
+    this._labels = labels2;
   }
   /**
    * Set the local variables defined within this executable element to the given variables.
    * @param localVariables the local variables defined within this executable element
    */
-  void set localVariables2(List<VariableElement> localVariables) {
-    for (VariableElement variable in localVariables) {
-      (variable as VariableElementImpl).enclosingElement2 = this;
+  void set localVariables(List<VariableElement> localVariables2) {
+    for (VariableElement variable in localVariables2) {
+      ((variable as VariableElementImpl)).enclosingElement = this;
     }
-    this._localVariables = localVariables;
+    this._localVariables = localVariables2;
   }
   /**
    * Set the parameters defined by this executable element to the given parameters.
    * @param parameters the parameters defined by this executable element
    */
-  void set parameters7(List<ParameterElement> parameters) {
-    for (ParameterElement parameter in parameters) {
-      (parameter as ParameterElementImpl).enclosingElement2 = this;
+  void set parameters(List<ParameterElement> parameters7) {
+    for (ParameterElement parameter in parameters7) {
+      ((parameter as ParameterElementImpl)).enclosingElement = this;
     }
-    this._parameters = parameters;
+    this._parameters = parameters7;
   }
   /**
    * Set the type of function defined by this executable element to the given type.
    * @param type the type of function defined by this executable element
    */
-  void set type11(FunctionType type) {
-    this._type = type;
+  void set type(FunctionType type6) {
+    this._type = type6;
+  }
+  void appendTo(StringBuffer builder) {
+    builder.add("(");
+    int parameterCount = _parameters.length;
+    for (int i = 0; i < parameterCount; i++) {
+      if (i > 0) {
+        builder.add(", ");
+      }
+      ((_parameters[i] as ParameterElementImpl)).appendTo(builder);
+    }
+    builder.add(")");
+    if (_type != null) {
+      builder.add(" -> ");
+      builder.add(_type.returnType);
+    }
   }
 }
 /**
@@ -1458,16 +1827,20 @@
    * combinators.
    * @param combinators the combinators that were specified as part of the export directive
    */
-  void set combinators2(List<NamespaceCombinator> combinators) {
-    this._combinators = combinators;
+  void set combinators(List<NamespaceCombinator> combinators2) {
+    this._combinators = combinators2;
   }
   /**
    * Set the library that is exported from this library by this import directive to the given
    * library.
    * @param exportedLibrary the library that is exported from this library
    */
-  void set exportedLibrary2(LibraryElement exportedLibrary) {
-    this._exportedLibrary = exportedLibrary;
+  void set exportedLibrary(LibraryElement exportedLibrary2) {
+    this._exportedLibrary = exportedLibrary2;
+  }
+  void appendTo(StringBuffer builder) {
+    builder.add("export ");
+    ((_exportedLibrary as LibraryElementImpl)).appendTo(builder);
   }
 }
 /**
@@ -1491,18 +1864,18 @@
    * @param name the name of this element
    */
   FieldElementImpl.con1(Identifier name) : super.con1(name) {
-    _jtd_constructor_136_impl(name);
+    _jtd_constructor_142_impl(name);
   }
-  _jtd_constructor_136_impl(Identifier name) {
+  _jtd_constructor_142_impl(Identifier name) {
   }
   /**
    * Initialize a newly created synthetic field element to have the given name.
    * @param name the name of this element
    */
   FieldElementImpl.con2(String name) : super.con2(name, -1) {
-    _jtd_constructor_137_impl(name);
+    _jtd_constructor_143_impl(name);
   }
-  _jtd_constructor_137_impl(String name) {
+  _jtd_constructor_143_impl(String name) {
     synthetic = true;
   }
   PropertyAccessorElement get getter => _getter;
@@ -1513,15 +1886,15 @@
    * Set the getter associated with this field to the given accessor.
    * @param getter the getter associated with this field
    */
-  void set getter2(PropertyAccessorElement getter) {
-    this._getter = getter;
+  void set getter(PropertyAccessorElement getter2) {
+    this._getter = getter2;
   }
   /**
    * Set the setter associated with this field to the given accessor.
    * @param setter the setter associated with this field
    */
-  void set setter2(PropertyAccessorElement setter) {
-    this._setter = setter;
+  void set setter(PropertyAccessorElement setter2) {
+    this._setter = setter2;
   }
   /**
    * Set whether this field is static to correspond to the given value.
@@ -1530,13 +1903,21 @@
   void set static(bool isStatic) {
     setModifier(Modifier.STATIC, isStatic);
   }
-  String toString() => "field ${type} ${name}";
 }
 /**
  * Instances of the class {@code FunctionElementImpl} implement a {@code FunctionElement}.
  */
 class FunctionElementImpl extends ExecutableElementImpl implements FunctionElement {
   /**
+   * The offset to the beginning of the visible range for this element.
+   */
+  int _visibleRangeOffset = 0;
+  /**
+   * The length of the visible range for this element, or {@code -1} if this element does not have a
+   * visible range.
+   */
+  int _visibleRangeLength = -1;
+  /**
    * An empty array of function elements.
    */
   static List<FunctionElement> EMPTY_ARRAY = new List<FunctionElement>.fixedLength(0);
@@ -1544,9 +1925,9 @@
    * Initialize a newly created synthetic function element.
    */
   FunctionElementImpl() : super.con2("", -1) {
-    _jtd_constructor_138_impl();
+    _jtd_constructor_144_impl();
   }
-  _jtd_constructor_138_impl() {
+  _jtd_constructor_144_impl() {
     synthetic = true;
   }
   /**
@@ -1554,12 +1935,36 @@
    * @param name the name of this element
    */
   FunctionElementImpl.con1(Identifier name) : super.con1(name) {
-    _jtd_constructor_139_impl(name);
+    _jtd_constructor_145_impl(name);
   }
-  _jtd_constructor_139_impl(Identifier name) {
+  _jtd_constructor_145_impl(Identifier name) {
   }
   String get identifier => name;
   ElementKind get kind => ElementKind.FUNCTION;
+  SourceRange get visibleRange {
+    if (_visibleRangeLength < 0) {
+      return null;
+    }
+    return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
+  }
+  /**
+   * Set the visible range for this element to the range starting at the given offset with the given
+   * length.
+   * @param offset the offset to the beginning of the visible range for this element
+   * @param length the length of the visible range for this element, or {@code -1} if this element
+   * does not have a visible range
+   */
+  void setVisibleRange(int offset, int length) {
+    _visibleRangeOffset = offset;
+    _visibleRangeLength = length;
+  }
+  void appendTo(StringBuffer builder) {
+    String name13 = name;
+    if (name13 != null) {
+      builder.add(name13);
+    }
+    super.appendTo(builder);
+  }
 }
 /**
  * Instances of the class {@code ShowCombinatorImpl} implement a {@link ShowCombinator}.
@@ -1581,8 +1986,20 @@
    * in the imported library to the given names.
    * @param hiddenNames the names that are not to be made visible in the importing library
    */
-  void set hiddenNames2(List<String> hiddenNames) {
-    this._hiddenNames = hiddenNames;
+  void set hiddenNames(List<String> hiddenNames2) {
+    this._hiddenNames = hiddenNames2;
+  }
+  String toString() {
+    StringBuffer builder = new StringBuffer();
+    builder.add("show ");
+    int count = _hiddenNames.length;
+    for (int i = 0; i < count; i++) {
+      if (i > 0) {
+        builder.add(", ");
+      }
+      builder.add(_hiddenNames[i]);
+    }
+    return builder.toString();
   }
 }
 /**
@@ -1613,7 +2030,7 @@
   HtmlElementImpl(AnalysisContext context, String name) : super.con2(name, -1) {
     this._context = context;
   }
-  bool operator ==(Object object) => this.runtimeType == object.runtimeType && _source == (object as CompilationUnitElementImpl).source;
+  bool operator ==(Object object) => identical(this.runtimeType, object.runtimeType) && _source == ((object as CompilationUnitElementImpl)).source;
   AnalysisContext get context => _context;
   ElementKind get kind => ElementKind.HTML;
   List<LibraryElement> get libraries => _libraries;
@@ -1624,15 +2041,22 @@
    * libraries.
    * @param libraries the libraries contained in or referenced from script tags in the HTML file
    */
-  void set libraries2(List<LibraryElement> libraries) {
-    this._libraries = libraries;
+  void set libraries(List<LibraryElement> libraries2) {
+    this._libraries = libraries2;
   }
   /**
    * Set the source that corresponds to this HTML file to the given source.
    * @param source the source that corresponds to this HTML file
    */
-  void set source4(Source source) {
-    this._source = source;
+  void set source(Source source6) {
+    this._source = source6;
+  }
+  void appendTo(StringBuffer builder) {
+    if (_source == null) {
+      builder.add("{HTML file}");
+    } else {
+      builder.add(_source.fullName);
+    }
   }
 }
 /**
@@ -1667,23 +2091,27 @@
    * combinators.
    * @param combinators the combinators that were specified as part of the import directive
    */
-  void set combinators3(List<NamespaceCombinator> combinators) {
-    this._combinators = combinators;
+  void set combinators(List<NamespaceCombinator> combinators3) {
+    this._combinators = combinators3;
   }
   /**
    * Set the library that is imported into this library by this import directive to the given
    * library.
    * @param importedLibrary the library that is imported into this library
    */
-  void set importedLibrary2(LibraryElement importedLibrary) {
-    this._importedLibrary = importedLibrary;
+  void set importedLibrary(LibraryElement importedLibrary3) {
+    this._importedLibrary = importedLibrary3;
   }
   /**
    * Set the prefix that was specified as part of the import directive to the given prefix.
    * @param prefix the prefix that was specified as part of the import directive
    */
-  void set prefix4(PrefixElement prefix) {
-    this._prefix = prefix;
+  void set prefix(PrefixElement prefix3) {
+    this._prefix = prefix3;
+  }
+  void appendTo(StringBuffer builder) {
+    builder.add("import ");
+    ((_importedLibrary as LibraryElementImpl)).appendTo(builder);
   }
 }
 /**
@@ -1712,7 +2140,7 @@
     this._onSwitchStatement = onSwitchStatement;
     this._onSwitchMember = onSwitchMember;
   }
-  ExecutableElement get enclosingElement => super.enclosingElement as ExecutableElement;
+  ExecutableElement get enclosingElement => (super.enclosingElement as ExecutableElement);
   ElementKind get kind => ElementKind.LABEL;
   /**
    * Return {@code true} if this label is associated with a {@code switch} member ({@code case} or{@code default}).
@@ -1765,14 +2193,14 @@
   LibraryElementImpl(AnalysisContext context, LibraryIdentifier name) : super.con1(name) {
     this._context = context;
   }
-  bool operator ==(Object object) => this.runtimeType == object.runtimeType && _definingCompilationUnit == (object as LibraryElementImpl).definingCompilationUnit;
-  ElementImpl getChild(String identifier) {
-    if ((_definingCompilationUnit as CompilationUnitElementImpl).identifier == identifier) {
-      return _definingCompilationUnit as CompilationUnitElementImpl;
+  bool operator ==(Object object) => identical(this.runtimeType, object.runtimeType) && _definingCompilationUnit == ((object as LibraryElementImpl)).definingCompilationUnit;
+  ElementImpl getChild(String identifier22) {
+    if (((_definingCompilationUnit as CompilationUnitElementImpl)).identifier == identifier22) {
+      return (_definingCompilationUnit as CompilationUnitElementImpl);
     }
     for (CompilationUnitElement part in _parts) {
-      if ((part as CompilationUnitElementImpl).identifier == identifier) {
-        return part as CompilationUnitElementImpl;
+      if (((part as CompilationUnitElementImpl)).identifier == identifier22) {
+        return (part as CompilationUnitElementImpl);
       }
     }
     return null;
@@ -1780,6 +2208,14 @@
   AnalysisContext get context => _context;
   CompilationUnitElement get definingCompilationUnit => _definingCompilationUnit;
   FunctionElement get entryPoint => _entryPoint;
+  List<LibraryElement> get exportedLibraries {
+    Set<LibraryElement> libraries = new Set<LibraryElement>();
+    for (ExportElement element in _exports) {
+      LibraryElement library = element.exportedLibrary;
+      javaSetAdd(libraries, library);
+    }
+    return new List.from(libraries);
+  }
   List<ExportElement> get exports => _exports;
   String get identifier => _definingCompilationUnit.source.fullName;
   List<LibraryElement> get importedLibraries {
@@ -1796,53 +2232,81 @@
   List<PrefixElement> get prefixes {
     Set<PrefixElement> prefixes = new Set<PrefixElement>();
     for (ImportElement element in _imports) {
-      PrefixElement prefix5 = element.prefix;
-      if (prefix5 != null) {
-        javaSetAdd(prefixes, prefix5);
+      PrefixElement prefix4 = element.prefix;
+      if (prefix4 != null) {
+        javaSetAdd(prefixes, prefix4);
       }
     }
     return new List.from(prefixes);
   }
   int get hashCode => _definingCompilationUnit.hashCode;
+  bool isBrowserApplication() => _entryPoint != null && isOrImportsBrowserLibrary();
   /**
    * Set the compilation unit that defines this library to the given compilation unit.
    * @param definingCompilationUnit the compilation unit that defines this library
    */
-  void set definingCompilationUnit2(CompilationUnitElement definingCompilationUnit) {
-    (definingCompilationUnit as CompilationUnitElementImpl).enclosingElement2 = this;
-    this._definingCompilationUnit = definingCompilationUnit;
+  void set definingCompilationUnit(CompilationUnitElement definingCompilationUnit2) {
+    ((definingCompilationUnit2 as CompilationUnitElementImpl)).enclosingElement = this;
+    this._definingCompilationUnit = definingCompilationUnit2;
   }
   /**
    * Set the entry point for this library to the given function.
    * @param entryPoint the entry point for this library
    */
-  void set entryPoint2(FunctionElement entryPoint) {
-    (entryPoint as FunctionElementImpl).enclosingElement2 = this;
-    this._entryPoint = entryPoint;
+  void set entryPoint(FunctionElement entryPoint2) {
+    ((entryPoint2 as FunctionElementImpl)).enclosingElement = this;
+    this._entryPoint = entryPoint2;
   }
   /**
    * Set the specifications of all of the exports defined in this library to the given array.
    * @param exports the specifications of all of the exports defined in this library
    */
-  void set exports2(List<ExportElement> exports) {
-    this._exports = exports;
+  void set exports(List<ExportElement> exports2) {
+    this._exports = exports2;
   }
   /**
    * Set the specifications of all of the imports defined in this library to the given array.
    * @param imports the specifications of all of the imports defined in this library
    */
-  void set imports2(List<ImportElement> imports) {
-    this._imports = imports;
+  void set imports(List<ImportElement> imports2) {
+    this._imports = imports2;
   }
   /**
    * Set the compilation units that are included in this library using a {@code part} directive.
    * @param parts the compilation units that are included in this library using a {@code part}directive
    */
-  void set parts2(List<CompilationUnitElement> parts) {
-    for (CompilationUnitElement compilationUnit in parts) {
-      (compilationUnit as CompilationUnitElementImpl).enclosingElement2 = this;
+  void set parts(List<CompilationUnitElement> parts2) {
+    for (CompilationUnitElement compilationUnit in parts2) {
+      ((compilationUnit as CompilationUnitElementImpl)).enclosingElement = this;
     }
-    this._parts = parts;
+    this._parts = parts2;
+  }
+  /**
+   * Answer {@code true} if the receiver directly or indirectly imports the dart:html libraries.
+   * @return {@code true} if the receiver directly or indirectly imports the dart:html libraries
+   */
+  bool isOrImportsBrowserLibrary() {
+    List<LibraryElement> visited = new List<LibraryElement>(10);
+    Source htmlLibSource = definingCompilationUnit.source.resolve(DartSdk.DART_HTML);
+    visited.add(this);
+    for (int index = 0; index < visited.length; index++) {
+      LibraryElement library = visited[index];
+      Source source8 = library.definingCompilationUnit.source;
+      if (source8 == htmlLibSource) {
+        return true;
+      }
+      for (LibraryElement importedLibrary in library.importedLibraries) {
+        if (!visited.contains(importedLibrary)) {
+          visited.add(importedLibrary);
+        }
+      }
+      for (LibraryElement exportedLibrary in library.exportedLibraries) {
+        if (!visited.contains(exportedLibrary)) {
+          visited.add(exportedLibrary);
+        }
+      }
+    }
+    return false;
   }
 }
 /**
@@ -1857,9 +2321,23 @@
    * Initialize a newly created method element to have the given name.
    * @param name the name of this element
    */
-  MethodElementImpl(Identifier name) : super.con1(name) {
+  MethodElementImpl.con1(Identifier name) : super.con1(name) {
+    _jtd_constructor_151_impl(name);
   }
-  ClassElement get enclosingElement => super.enclosingElement as ClassElement;
+  _jtd_constructor_151_impl(Identifier name) {
+  }
+  /**
+   * Initialize a newly created method element to have the given name.
+   * @param name the name of this element
+   * @param nameOffset the offset of the name of this element in the file that contains the
+   * declaration of this element
+   */
+  MethodElementImpl.con2(String name, int nameOffset) : super.con2(name, nameOffset) {
+    _jtd_constructor_152_impl(name, nameOffset);
+  }
+  _jtd_constructor_152_impl(String name, int nameOffset) {
+  }
+  ClassElement get enclosingElement => (super.enclosingElement as ClassElement);
   ElementKind get kind => ElementKind.METHOD;
   bool isAbstract() => hasModifier(Modifier.ABSTRACT);
   bool isStatic() => hasModifier(Modifier.STATIC);
@@ -1877,19 +2355,16 @@
   void set static(bool isStatic) {
     setModifier(Modifier.STATIC, isStatic);
   }
-  String toString() {
-    StringBuffer builder = new StringBuffer();
-    builder.add("method ");
+  void appendTo(StringBuffer builder) {
     builder.add(enclosingElement.name);
     builder.add(".");
     builder.add(name);
-    builder.add(type);
-    return builder.toString();
+    super.appendTo(builder);
   }
 }
 /**
  * The enumeration {@code Modifier} defines constants for all of the modifiers defined by the Dart
- * language.
+ * language and for a few additional flags that are useful.
  */
 class Modifier {
   static final Modifier ABSTRACT = new Modifier('ABSTRACT', 0);
@@ -1897,10 +2372,11 @@
   static final Modifier FACTORY = new Modifier('FACTORY', 2);
   static final Modifier FINAL = new Modifier('FINAL', 3);
   static final Modifier GETTER = new Modifier('GETTER', 4);
-  static final Modifier SETTER = new Modifier('SETTER', 5);
-  static final Modifier STATIC = new Modifier('STATIC', 6);
-  static final Modifier SYNTHETIC = new Modifier('SYNTHETIC', 7);
-  static final List<Modifier> values = [ABSTRACT, CONST, FACTORY, FINAL, GETTER, SETTER, STATIC, SYNTHETIC];
+  static final Modifier INITIALIZING_FORMAL = new Modifier('INITIALIZING_FORMAL', 5);
+  static final Modifier SETTER = new Modifier('SETTER', 6);
+  static final Modifier STATIC = new Modifier('STATIC', 7);
+  static final Modifier SYNTHETIC = new Modifier('SYNTHETIC', 8);
+  static final List<Modifier> values = [ABSTRACT, CONST, FACTORY, FINAL, GETTER, INITIALIZING_FORMAL, SETTER, STATIC, SYNTHETIC];
   final String __name;
   final int __ordinal;
   Modifier(this.__name, this.__ordinal) {
@@ -1944,7 +2420,29 @@
   List<Annotation> get metadata => AnnotationImpl.EMPTY_ARRAY;
   String get name => _name;
   int get nameOffset => -1;
+  Source get source => null;
+  bool isAccessibleIn(LibraryElement library) {
+    for (Element element in _conflictingElements) {
+      if (element.isAccessibleIn(library)) {
+        return true;
+      }
+    }
+    return false;
+  }
   bool isSynthetic() => true;
+  String toString() {
+    StringBuffer builder = new StringBuffer();
+    builder.add("[");
+    int count = _conflictingElements.length;
+    for (int i = 0; i < count; i++) {
+      if (i > 0) {
+        builder.add(", ");
+      }
+      ((_conflictingElements[i] as ElementImpl)).appendTo(builder);
+    }
+    builder.add("]");
+    return builder.toString();
+  }
   /**
    * Add the given element to the list of elements. If the element is a multiply-defined element,
    * add all of the conflicting elements that it represents.
@@ -1953,7 +2451,7 @@
    */
   void add(List<Element> elements, Element element) {
     if (element is MultiplyDefinedElementImpl) {
-      for (Element conflictingElement in (element as MultiplyDefinedElementImpl)._conflictingElements) {
+      for (Element conflictingElement in ((element as MultiplyDefinedElementImpl))._conflictingElements) {
         elements.add(conflictingElement);
       }
     } else {
@@ -1995,14 +2493,29 @@
   }
   ElementKind get kind => ElementKind.PARAMETER;
   ParameterKind get parameterKind => _parameterKind;
+  bool isInitializingFormal() => hasModifier(Modifier.INITIALIZING_FORMAL);
+  /**
+   * Set whether this parameter is an initializing formal parameter to match the given value.
+   * @param isInitializingFormal {@code true} if this parameter is an initializing formal parameter
+   */
+  void set initializingFormal(bool isInitializingFormal) {
+    setModifier(Modifier.INITIALIZING_FORMAL, isInitializingFormal);
+  }
   /**
    * Set the kind of this parameter to the given kind.
    * @param parameterKind the new kind of this parameter
    */
-  void set parameterKind2(ParameterKind parameterKind) {
-    this._parameterKind = parameterKind;
+  void set parameterKind(ParameterKind parameterKind2) {
+    this._parameterKind = parameterKind2;
   }
-  String toString() => "parameter ${type} ${name} (${kind})";
+  void appendTo(StringBuffer builder) {
+    builder.add(type);
+    builder.add(" ");
+    builder.add(name);
+    builder.add(" (");
+    builder.add(kind);
+    builder.add(")");
+  }
 }
 /**
  * Instances of the class {@code PrefixElementImpl} implement a {@code PrefixElement}.
@@ -2022,18 +2535,22 @@
    */
   PrefixElementImpl(Identifier name) : super.con1(name) {
   }
-  LibraryElement get enclosingElement => super.enclosingElement as LibraryElement;
+  LibraryElement get enclosingElement => (super.enclosingElement as LibraryElement);
   List<LibraryElement> get importedLibraries => _importedLibraries;
   ElementKind get kind => ElementKind.PREFIX;
   /**
    * Set the libraries that are imported using this prefix to the given libraries.
    * @param importedLibraries the libraries that are imported using this prefix
    */
-  void set importedLibraries2(List<LibraryElement> importedLibraries) {
-    for (LibraryElement library in importedLibraries) {
-      (library as LibraryElementImpl).enclosingElement2 = this;
+  void set importedLibraries(List<LibraryElement> importedLibraries2) {
+    for (LibraryElement library in importedLibraries2) {
+      ((library as LibraryElementImpl)).enclosingElement = this;
     }
-    this._importedLibraries = importedLibraries;
+    this._importedLibraries = importedLibraries2;
+  }
+  void appendTo(StringBuffer builder) {
+    builder.add("as ");
+    super.appendTo(builder);
   }
 }
 /**
@@ -2053,11 +2570,11 @@
    * field.
    * @param name the name of this element
    */
-  PropertyAccessorElementImpl.con1(FieldElementImpl field) : super.con2(field.name, -1) {
-    _jtd_constructor_150_impl(field);
+  PropertyAccessorElementImpl.con1(FieldElementImpl field2) : super.con2(field2.name, -1) {
+    _jtd_constructor_157_impl(field2);
   }
-  _jtd_constructor_150_impl(FieldElementImpl field) {
-    this._field = field;
+  _jtd_constructor_157_impl(FieldElementImpl field2) {
+    this._field = field2;
     synthetic = true;
   }
   /**
@@ -2065,9 +2582,9 @@
    * @param name the name of this element
    */
   PropertyAccessorElementImpl.con2(Identifier name) : super.con1(name) {
-    _jtd_constructor_151_impl(name);
+    _jtd_constructor_158_impl(name);
   }
-  _jtd_constructor_151_impl(Identifier name) {
+  _jtd_constructor_158_impl(Identifier name) {
   }
   FieldElement get field => _field;
   ElementKind get kind {
@@ -2082,8 +2599,8 @@
    * Set the field associated with this accessor to the given field.
    * @param field the field associated with this accessor
    */
-  void set field2(FieldElement field) {
-    this._field = field;
+  void set field(FieldElement field3) {
+    this._field = field3;
   }
   /**
    * Set whether this accessor is a getter to correspond to the given value.
@@ -2099,6 +2616,11 @@
   void set setter(bool isSetter) {
     setModifier(Modifier.SETTER, isSetter);
   }
+  void appendTo(StringBuffer builder) {
+    builder.add(isGetter() ? "get " : "set ");
+    builder.add(field.name);
+    super.appendTo(builder);
+  }
 }
 /**
  * Instances of the class {@code ShowCombinatorImpl} implement a {@link ShowCombinator}.
@@ -2120,8 +2642,20 @@
    * imported library to the given names.
    * @param shownNames the names that are to be made visible in the importing library
    */
-  void set shownNames2(List<String> shownNames) {
-    this._shownNames = shownNames;
+  void set shownNames(List<String> shownNames2) {
+    this._shownNames = shownNames2;
+  }
+  String toString() {
+    StringBuffer builder = new StringBuffer();
+    builder.add("show ");
+    int count = _shownNames.length;
+    for (int i = 0; i < count; i++) {
+      if (i > 0) {
+        builder.add(", ");
+      }
+      builder.add(_shownNames[i]);
+    }
+    return builder.toString();
   }
 }
 /**
@@ -2150,20 +2684,20 @@
    */
   TypeAliasElementImpl(Identifier name) : super.con1(name) {
   }
-  ElementImpl getChild(String identifier) {
+  ElementImpl getChild(String identifier23) {
     for (VariableElement parameter in _parameters) {
-      if ((parameter as VariableElementImpl).identifier == identifier) {
-        return parameter as VariableElementImpl;
+      if (((parameter as VariableElementImpl)).identifier == identifier23) {
+        return (parameter as VariableElementImpl);
       }
     }
     for (TypeVariableElement typeVariable in _typeVariables) {
-      if ((typeVariable as TypeVariableElementImpl).identifier == identifier) {
-        return typeVariable as TypeVariableElementImpl;
+      if (((typeVariable as TypeVariableElementImpl)).identifier == identifier23) {
+        return (typeVariable as TypeVariableElementImpl);
       }
     }
     return null;
   }
-  CompilationUnitElement get enclosingElement => super.enclosingElement as CompilationUnitElement;
+  CompilationUnitElement get enclosingElement => (super.enclosingElement as CompilationUnitElement);
   ElementKind get kind => ElementKind.TYPE_ALIAS;
   List<ParameterElement> get parameters => _parameters;
   FunctionType get type => _type;
@@ -2172,30 +2706,58 @@
    * Set the parameters defined by this type alias to the given parameters.
    * @param parameters the parameters defined by this type alias
    */
-  void set parameters8(List<ParameterElement> parameters) {
-    if (parameters != null) {
-      for (ParameterElement parameter in parameters) {
-        (parameter as ParameterElementImpl).enclosingElement2 = this;
+  void set parameters(List<ParameterElement> parameters8) {
+    if (parameters8 != null) {
+      for (ParameterElement parameter in parameters8) {
+        ((parameter as ParameterElementImpl)).enclosingElement = this;
       }
     }
-    this._parameters = parameters;
+    this._parameters = parameters8;
   }
   /**
    * Set the type of function defined by this type alias to the given type.
    * @param type the type of function defined by this type alias
    */
-  void set type12(FunctionType type) {
-    this._type = type;
+  void set type(FunctionType type7) {
+    this._type = type7;
   }
   /**
    * Set the type variables defined for this type to the given variables.
    * @param typeVariables the type variables defined for this type
    */
-  void set typeVariables3(List<TypeVariableElement> typeVariables) {
-    for (TypeVariableElement variable in typeVariables) {
-      (variable as TypeVariableElementImpl).enclosingElement2 = this;
+  void set typeVariables(List<TypeVariableElement> typeVariables3) {
+    for (TypeVariableElement variable in typeVariables3) {
+      ((variable as TypeVariableElementImpl)).enclosingElement = this;
     }
-    this._typeVariables = typeVariables;
+    this._typeVariables = typeVariables3;
+  }
+  void appendTo(StringBuffer builder) {
+    builder.add("typedef ");
+    builder.add(name);
+    int variableCount = _typeVariables.length;
+    if (variableCount > 0) {
+      builder.add("<");
+      for (int i = 0; i < variableCount; i++) {
+        if (i > 0) {
+          builder.add(", ");
+        }
+        ((_typeVariables[i] as TypeVariableElementImpl)).appendTo(builder);
+      }
+      builder.add(">");
+    }
+    builder.add("(");
+    int parameterCount = _parameters.length;
+    for (int i = 0; i < parameterCount; i++) {
+      if (i > 0) {
+        builder.add(", ");
+      }
+      ((_parameters[i] as ParameterElementImpl)).appendTo(builder);
+    }
+    builder.add(")");
+    if (_type != null) {
+      builder.add(" -> ");
+      builder.add(_type.returnType);
+    }
   }
 }
 /**
@@ -2228,15 +2790,22 @@
    * Set the type representing the bound associated with this variable to the given type.
    * @param bound the type representing the bound associated with this variable
    */
-  void set bound3(Type2 bound) {
-    this._bound = bound;
+  void set bound(Type2 bound2) {
+    this._bound = bound2;
   }
   /**
    * Set the type defined by this type variable to the given type
    * @param type the type defined by this type variable
    */
-  void set type13(TypeVariableType type) {
-    this._type = type;
+  void set type(TypeVariableType type8) {
+    this._type = type8;
+  }
+  void appendTo(StringBuffer builder) {
+    builder.add(name);
+    if (_bound != null) {
+      builder.add(" extends ");
+      builder.add(_bound);
+    }
   }
 }
 /**
@@ -2253,6 +2822,15 @@
    */
   FunctionElement _initializer;
   /**
+   * The offset to the beginning of the visible range for this element.
+   */
+  int _visibleRangeOffset = 0;
+  /**
+   * The length of the visible range for this element, or {@code -1} if this element does not have a
+   * visible range.
+   */
+  int _visibleRangeLength = -1;
+  /**
    * An empty array of variable elements.
    */
   static List<VariableElement> EMPTY_ARRAY = new List<VariableElement>.fixedLength(0);
@@ -2261,9 +2839,9 @@
    * @param name the name of this element
    */
   VariableElementImpl.con1(Identifier name) : super.con1(name) {
-    _jtd_constructor_155_impl(name);
+    _jtd_constructor_162_impl(name);
   }
-  _jtd_constructor_155_impl(Identifier name) {
+  _jtd_constructor_162_impl(Identifier name) {
   }
   /**
    * Initialize a newly created variable element to have the given name.
@@ -2272,13 +2850,19 @@
    * declaration of this element
    */
   VariableElementImpl.con2(String name, int nameOffset) : super.con2(name, nameOffset) {
-    _jtd_constructor_156_impl(name, nameOffset);
+    _jtd_constructor_163_impl(name, nameOffset);
   }
-  _jtd_constructor_156_impl(String name, int nameOffset) {
+  _jtd_constructor_163_impl(String name, int nameOffset) {
   }
   FunctionElement get initializer => _initializer;
   ElementKind get kind => ElementKind.VARIABLE;
   Type2 get type => _type;
+  SourceRange get visibleRange {
+    if (_visibleRangeLength < 0) {
+      return null;
+    }
+    return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
+  }
   bool isConst() => hasModifier(Modifier.CONST);
   bool isFinal() => hasModifier(Modifier.FINAL);
   /**
@@ -2299,20 +2883,35 @@
    * Set the function representing this variable's initializer to the given function.
    * @param initializer the function representing this variable's initializer
    */
-  void set initializer3(FunctionElement initializer) {
-    if (initializer != null) {
-      (initializer as FunctionElementImpl).enclosingElement2 = this;
+  void set initializer(FunctionElement initializer3) {
+    if (initializer3 != null) {
+      ((initializer3 as FunctionElementImpl)).enclosingElement = this;
     }
-    this._initializer = initializer;
+    this._initializer = initializer3;
   }
   /**
    * Set the declared type of this variable to the given type.
    * @param type the declared type of this variable
    */
-  void set type14(Type2 type) {
-    this._type = type;
+  void set type(Type2 type9) {
+    this._type = type9;
   }
-  String toString() => "variable ${type} ${name}";
+  /**
+   * Set the visible range for this element to the range starting at the given offset with the given
+   * length.
+   * @param offset the offset to the beginning of the visible range for this element
+   * @param length the length of the visible range for this element, or {@code -1} if this element
+   * does not have a visible range
+   */
+  void setVisibleRange(int offset, int length) {
+    _visibleRangeOffset = offset;
+    _visibleRangeLength = length;
+  }
+  void appendTo(StringBuffer builder) {
+    builder.add(type);
+    builder.add(" ");
+    builder.add(name);
+  }
 }
 /**
  * The unique instance of the class {@code BottomTypeImpl} implements the type {@code bottom}.
@@ -2332,7 +2931,7 @@
    */
   BottomTypeImpl() : super(null, "<bottom>") {
   }
-  bool operator ==(Object object) => object == this;
+  bool operator ==(Object object) => identical(object, this);
   bool isMoreSpecificThan(Type2 type) => true;
   bool isSubtypeOf(Type2 type) => true;
   bool isSupertypeOf(Type2 type) => false;
@@ -2355,7 +2954,7 @@
    * Prevent the creation of instances of this class.
    */
   DynamicTypeImpl() : super(new DynamicElementImpl(), Keyword.DYNAMIC.syntax) {
-    (element as DynamicElementImpl).type10 = this;
+    ((element as DynamicElementImpl)).type = this;
   }
   bool operator ==(Object object) => object is DynamicTypeImpl;
   bool isMoreSpecificThan(Type2 type) => false;
@@ -2380,8 +2979,8 @@
     if (secondTypes.length != firstTypes.length) {
       return false;
     }
-    HasNextIterator<MapEntry<String, Type2>> firstIterator = new HasNextIterator(getMapEntrySet(firstTypes).iterator);
-    HasNextIterator<MapEntry<String, Type2>> secondIterator = new HasNextIterator(getMapEntrySet(firstTypes).iterator);
+    JavaIterator<MapEntry<String, Type2>> firstIterator = new JavaIterator(getMapEntrySet(firstTypes));
+    JavaIterator<MapEntry<String, Type2>> secondIterator = new JavaIterator(getMapEntrySet(firstTypes));
     while (firstIterator.hasNext) {
       MapEntry<String, Type2> firstEntry = firstIterator.next();
       MapEntry<String, Type2> secondEntry = secondIterator.next();
@@ -2437,9 +3036,9 @@
    * @param element the element representing the declaration of the function type
    */
   FunctionTypeImpl.con1(ExecutableElement element) : super(element, element == null ? null : element.name) {
-    _jtd_constructor_200_impl(element);
+    _jtd_constructor_209_impl(element);
   }
-  _jtd_constructor_200_impl(ExecutableElement element) {
+  _jtd_constructor_209_impl(ExecutableElement element) {
   }
   /**
    * Initialize a newly created function type to be declared by the given element and to have the
@@ -2447,15 +3046,15 @@
    * @param element the element representing the declaration of the function type
    */
   FunctionTypeImpl.con2(TypeAliasElement element) : super(element, element == null ? null : element.name) {
-    _jtd_constructor_201_impl(element);
+    _jtd_constructor_210_impl(element);
   }
-  _jtd_constructor_201_impl(TypeAliasElement element) {
+  _jtd_constructor_210_impl(TypeAliasElement element) {
   }
   bool operator ==(Object object) {
     if (object is! FunctionTypeImpl) {
       return false;
     }
-    FunctionTypeImpl otherType = object as FunctionTypeImpl;
+    FunctionTypeImpl otherType = (object as FunctionTypeImpl);
     return element == otherType.element && JavaArrays.equals(_normalParameterTypes, otherType._normalParameterTypes) && JavaArrays.equals(_optionalParameterTypes, otherType._optionalParameterTypes) && equals2(_namedParameterTypes, otherType._namedParameterTypes);
   }
   Map<String, Type2> get namedParameterTypes => _namedParameterTypes;
@@ -2464,20 +3063,20 @@
   Type2 get returnType => _returnType;
   List<Type2> get typeArguments => _typeArguments;
   int get hashCode {
-    Element element29 = element;
-    if (element29 == null) {
+    Element element34 = element;
+    if (element34 == null) {
       return 0;
     }
-    return element29.hashCode;
+    return element34.hashCode;
   }
   bool isSubtypeOf(Type2 type) {
     if (type == null || type is! FunctionType) {
       return false;
-    } else if (this == type || this == type) {
+    } else if (identical(this, type) || this == type) {
       return true;
     }
     FunctionType t = this;
-    FunctionType s = type as FunctionType;
+    FunctionType s = (type as FunctionType);
     if (t.normalParameterTypes.length != s.normalParameterTypes.length) {
       return false;
     } else if (t.normalParameterTypes.length > 0) {
@@ -2512,7 +3111,7 @@
       if (namedTypesT.length < namedTypesS.length) {
         return false;
       }
-      HasNextIterator<MapEntry<String, Type2>> iteratorS = new HasNextIterator(getMapEntrySet(namedTypesS).iterator);
+      JavaIterator<MapEntry<String, Type2>> iteratorS = new JavaIterator(getMapEntrySet(namedTypesS));
       while (iteratorS.hasNext) {
         MapEntry<String, Type2> entryS = iteratorS.next();
         Type2 typeT = namedTypesT[entryS.getKey()];
@@ -2534,38 +3133,38 @@
    * @param namedParameterTypes the mapping of the names of named parameters to the types of the
    * named parameters of this type of function
    */
-  void set namedParameterTypes2(LinkedHashMap<String, Type2> namedParameterTypes) {
-    this._namedParameterTypes = namedParameterTypes;
+  void set namedParameterTypes(LinkedHashMap<String, Type2> namedParameterTypes2) {
+    this._namedParameterTypes = namedParameterTypes2;
   }
   /**
    * Set the types of the normal parameters of this type of function to the types in the given
    * array.
    * @param normalParameterTypes the types of the normal parameters of this type of function
    */
-  void set normalParameterTypes2(List<Type2> normalParameterTypes) {
-    this._normalParameterTypes = normalParameterTypes;
+  void set normalParameterTypes(List<Type2> normalParameterTypes2) {
+    this._normalParameterTypes = normalParameterTypes2;
   }
   /**
    * Set the types of the optional parameters of this type of function to the types in the given
    * array.
    * @param optionalParameterTypes the types of the optional parameters of this type of function
    */
-  void set optionalParameterTypes2(List<Type2> optionalParameterTypes) {
-    this._optionalParameterTypes = optionalParameterTypes;
+  void set optionalParameterTypes(List<Type2> optionalParameterTypes2) {
+    this._optionalParameterTypes = optionalParameterTypes2;
   }
   /**
    * Set the type of object returned by this type of function to the given type.
    * @param returnType the type of object returned by this type of function
    */
-  void set returnType7(Type2 returnType) {
-    this._returnType = returnType;
+  void set returnType(Type2 returnType3) {
+    this._returnType = returnType3;
   }
   /**
    * Set the actual types of the type arguments to the given types.
    * @param typeArguments the actual types of the type arguments
    */
-  void set typeArguments4(List<Type2> typeArguments) {
-    this._typeArguments = typeArguments;
+  void set typeArguments(List<Type2> typeArguments4) {
+    this._typeArguments = typeArguments4;
   }
   FunctionTypeImpl substitute4(List<Type2> argumentTypes) => substitute2(argumentTypes, typeArguments);
   FunctionTypeImpl substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) {
@@ -2575,16 +3174,15 @@
     if (argumentTypes.length == 0) {
       return this;
     }
-    Element element30 = element;
-    FunctionTypeImpl newType = (element30 is ExecutableElement) ? new FunctionTypeImpl.con1(element30 as ExecutableElement) : new FunctionTypeImpl.con2(element30 as TypeAliasElement);
-    newType.returnType7 = _returnType.substitute2(argumentTypes, parameterTypes);
-    newType.normalParameterTypes2 = TypeImpl.substitute(_normalParameterTypes, argumentTypes, parameterTypes);
-    newType.optionalParameterTypes2 = TypeImpl.substitute(_optionalParameterTypes, argumentTypes, parameterTypes);
-    newType.namedParameterTypes2 = substitute3(_namedParameterTypes, argumentTypes, parameterTypes);
+    Element element35 = element;
+    FunctionTypeImpl newType = (element35 is ExecutableElement) ? new FunctionTypeImpl.con1((element35 as ExecutableElement)) : new FunctionTypeImpl.con2((element35 as TypeAliasElement));
+    newType.returnType = _returnType.substitute2(argumentTypes, parameterTypes);
+    newType.normalParameterTypes = TypeImpl.substitute(_normalParameterTypes, argumentTypes, parameterTypes);
+    newType.optionalParameterTypes = TypeImpl.substitute(_optionalParameterTypes, argumentTypes, parameterTypes);
+    newType.namedParameterTypes = substitute3(_namedParameterTypes, argumentTypes, parameterTypes);
     return newType;
   }
-  String toString() {
-    StringBuffer builder = new StringBuffer();
+  void appendTo(StringBuffer builder) {
     builder.add("(");
     bool needsComma = false;
     if (_normalParameterTypes.length > 0) {
@@ -2594,7 +3192,7 @@
         } else {
           needsComma = true;
         }
-        builder.add(type);
+        ((type as TypeImpl)).appendTo(builder);
       }
     }
     if (_optionalParameterTypes.length > 0) {
@@ -2609,7 +3207,7 @@
         } else {
           needsComma = true;
         }
-        builder.add(type);
+        ((type as TypeImpl)).appendTo(builder);
       }
       builder.add("]");
       needsComma = true;
@@ -2628,14 +3226,13 @@
         }
         builder.add(entry.getKey());
         builder.add(": ");
-        builder.add(entry.getValue());
+        ((entry.getValue() as TypeImpl)).appendTo(builder);
       }
       builder.add("}");
       needsComma = true;
     }
     builder.add(") -> ");
-    builder.add(_returnType);
-    return builder.toString();
+    ((_returnType as TypeImpl)).appendTo(builder);
   }
 }
 /**
@@ -2706,9 +3303,9 @@
    * @see #getLeastUpperBound(Type)
    */
   static Set<InterfaceType> computeSuperinterfaceSet2(InterfaceType type, Set<InterfaceType> set) {
-    Element element31 = type.element;
-    if (element31 != null && element31 is ClassElement) {
-      ClassElement classElement = element31 as ClassElement;
+    Element element36 = type.element;
+    if (element36 != null && element36 is ClassElement) {
+      ClassElement classElement = (element36 as ClassElement);
       List<InterfaceType> superinterfaces = classElement.interfaces;
       for (InterfaceType superinterface in superinterfaces) {
         javaSetAdd(set, superinterface);
@@ -2731,9 +3328,9 @@
    * @param element the element representing the declaration of the type
    */
   InterfaceTypeImpl.con1(ClassElement element) : super(element, element.name) {
-    _jtd_constructor_202_impl(element);
+    _jtd_constructor_211_impl(element);
   }
-  _jtd_constructor_202_impl(ClassElement element) {
+  _jtd_constructor_211_impl(ClassElement element) {
   }
   /**
    * Initialize a newly created type to have the given name. This constructor should only be used in
@@ -2741,28 +3338,28 @@
    * @param name the name of the type
    */
   InterfaceTypeImpl.con2(String name) : super(null, name) {
-    _jtd_constructor_203_impl(name);
+    _jtd_constructor_212_impl(name);
   }
-  _jtd_constructor_203_impl(String name) {
+  _jtd_constructor_212_impl(String name) {
   }
   bool operator ==(Object object) {
     if (object is! InterfaceTypeImpl) {
       return false;
     }
-    InterfaceTypeImpl otherType = object as InterfaceTypeImpl;
+    InterfaceTypeImpl otherType = (object as InterfaceTypeImpl);
     return element == otherType.element && JavaArrays.equals(_typeArguments, otherType._typeArguments);
   }
-  ClassElement get element => super.element as ClassElement;
+  ClassElement get element => (super.element as ClassElement);
   Type2 getLeastUpperBound(Type2 type) {
     Type2 dynamicType = DynamicTypeImpl.instance;
-    if (this == dynamicType || type == dynamicType) {
+    if (identical(this, dynamicType) || identical(type, dynamicType)) {
       return dynamicType;
     }
     if (type == null || type is! InterfaceType) {
       return null;
     }
     InterfaceType i = this;
-    InterfaceType j = type as InterfaceType;
+    InterfaceType j = (type as InterfaceType);
     Set<InterfaceType> si = computeSuperinterfaceSet(i);
     Set<InterfaceType> sj = computeSuperinterfaceSet(j);
     javaSetAdd(si, i);
@@ -2799,42 +3396,42 @@
   }
   List<Type2> get typeArguments => _typeArguments;
   int get hashCode {
-    ClassElement element32 = element;
-    if (element32 == null) {
+    ClassElement element37 = element;
+    if (element37 == null) {
       return 0;
     }
-    return element32.hashCode;
+    return element37.hashCode;
   }
   bool isDirectSupertypeOf(InterfaceType type) {
     ClassElement i = element;
     ClassElement j = type.element;
-    Type2 supertype5 = j.supertype;
+    InterfaceType supertype5 = j.supertype;
     if (supertype5 == null) {
       return false;
     }
-    ClassElement supertypeElement = supertype5.element as ClassElement;
+    ClassElement supertypeElement = supertype5.element;
     if (supertypeElement == i) {
       return true;
     }
-    for (Type2 interfaceType in j.interfaces) {
-      if (interfaceType == i) {
+    for (InterfaceType interfaceType in j.interfaces) {
+      if (interfaceType.element == i) {
         return true;
       }
     }
-    for (Type2 mixinType in j.mixins) {
-      if (mixinType == i) {
+    for (InterfaceType mixinType in j.mixins) {
+      if (mixinType.element == i) {
         return true;
       }
     }
     return false;
   }
   bool isMoreSpecificThan(Type2 type) {
-    if (type == DynamicTypeImpl.instance) {
+    if (identical(type, DynamicTypeImpl.instance)) {
       return true;
     } else if (type is! InterfaceType) {
       return false;
     }
-    InterfaceType s = type as InterfaceType;
+    InterfaceType s = (type as InterfaceType);
     if (this == s) {
       return true;
     }
@@ -2862,7 +3459,7 @@
     return element.supertype.isMoreSpecificThan(type);
   }
   bool isSubtypeOf(Type2 type) {
-    if (type == DynamicTypeImpl.instance) {
+    if (identical(type, DynamicTypeImpl.instance)) {
       return true;
     } else if (type is TypeVariableType) {
       return true;
@@ -2872,7 +3469,7 @@
       return true;
     }
     InterfaceType typeT = this;
-    InterfaceType typeS = type as InterfaceType;
+    InterfaceType typeS = (type as InterfaceType);
     ClassElement elementT = element;
     if (elementT == null) {
       return false;
@@ -2915,8 +3512,8 @@
    * Set the actual types of the type arguments to those in the given array.
    * @param typeArguments the actual types of the type arguments
    */
-  void set typeArguments5(List<Type2> typeArguments) {
-    this._typeArguments = typeArguments;
+  void set typeArguments(List<Type2> typeArguments5) {
+    this._typeArguments = typeArguments5;
   }
   InterfaceTypeImpl substitute5(List<Type2> argumentTypes) => substitute2(argumentTypes, typeArguments);
   InterfaceTypeImpl substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) {
@@ -2927,9 +3524,23 @@
       return this;
     }
     InterfaceTypeImpl newType = new InterfaceTypeImpl.con1(element);
-    newType.typeArguments5 = TypeImpl.substitute(_typeArguments, argumentTypes, parameterTypes);
+    newType.typeArguments = TypeImpl.substitute(_typeArguments, argumentTypes, parameterTypes);
     return newType;
   }
+  void appendTo(StringBuffer builder) {
+    builder.add(name);
+    int argumentCount = _typeArguments.length;
+    if (argumentCount > 0) {
+      builder.add("<");
+      for (int i = 0; i < argumentCount; i++) {
+        if (i > 0) {
+          builder.add(", ");
+        }
+        ((_typeArguments[i] as TypeImpl)).appendTo(builder);
+      }
+      builder.add(">");
+    }
+  }
 }
 /**
  * The abstract class {@code TypeImpl} implements the behavior common to objects representing the
@@ -2980,7 +3591,22 @@
   bool isAssignableTo(Type2 type) => this.isSubtypeOf(type) || type.isSubtypeOf(this);
   bool isMoreSpecificThan(Type2 type) => false;
   bool isSupertypeOf(Type2 type) => type.isSubtypeOf(this);
-  String toString() => _name == null ? "<unnamed type>" : "type ${_name}";
+  String toString() {
+    StringBuffer builder = new StringBuffer();
+    appendTo(builder);
+    return builder.toString();
+  }
+  /**
+   * Append a textual representation of this type to the given builder.
+   * @param builder the builder to which the text is to be appended
+   */
+  void appendTo(StringBuffer builder) {
+    if (_name == null) {
+      builder.add("<unnamed type>");
+    } else {
+      builder.add(_name);
+    }
+  }
 }
 /**
  * Instances of the class {@code TypeVariableTypeImpl} defines the behavior of objects representing
@@ -3008,8 +3634,8 @@
    */
   TypeVariableTypeImpl(TypeVariableElement element) : super(element, element.name) {
   }
-  bool operator ==(Object object) => object is TypeVariableTypeImpl && element == (object as TypeVariableTypeImpl).element;
-  TypeVariableElement get element => super.element as TypeVariableElement;
+  bool operator ==(Object object) => object is TypeVariableTypeImpl && element == ((object as TypeVariableTypeImpl)).element;
+  TypeVariableElement get element => (super.element as TypeVariableElement);
   int get hashCode => element.hashCode;
   bool isMoreSpecificThan(Type2 type) {
     Type2 upperBound = element.bound;
@@ -3044,8 +3670,8 @@
    */
   VoidTypeImpl() : super(null, Keyword.VOID.syntax) {
   }
-  bool operator ==(Object object) => object == this;
-  bool isSubtypeOf(Type2 type) => type == this || type == DynamicTypeImpl.instance;
+  bool operator ==(Object object) => identical(object, this);
+  bool isSubtypeOf(Type2 type) => identical(type, this) || identical(type, DynamicTypeImpl.instance);
   VoidTypeImpl substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) => this;
 }
 /**
diff --git a/pkg/analyzer-experimental/lib/src/generated/engine.dart b/pkg/analyzer-experimental/lib/src/generated/engine.dart
new file mode 100644
index 0000000..20ab924
--- /dev/null
+++ b/pkg/analyzer-experimental/lib/src/generated/engine.dart
@@ -0,0 +1,660 @@
+// This code was auto-generated, is not intended to be edited, and is subject to
+// significant change. Please see the README file for more information.
+
+library engine;
+
+import 'java_core.dart';
+import 'dart:collection' show HasNextIterator;
+import 'error.dart';
+import 'source.dart';
+import 'scanner.dart' show Token, CharBufferScanner, StringScanner;
+import 'ast.dart' show CompilationUnit;
+import 'parser.dart' show Parser;
+import 'element.dart';
+import 'resolver.dart' show Namespace, NamespaceBuilder, LibraryResolver;
+
+/**
+ * The unique instance of the class {@code AnalysisEngine} serves as the entry point for the
+ * functionality provided by the analysis engine.
+ */
+class AnalysisEngine {
+  /**
+   * The unique instance of this class.
+   */
+  static AnalysisEngine _UniqueInstance = new AnalysisEngine();
+  /**
+   * Return the unique instance of this class.
+   * @return the unique instance of this class
+   */
+  static AnalysisEngine get instance => _UniqueInstance;
+  /**
+   * The logger that should receive information about errors within the analysis engine.
+   */
+  Logger _logger = Logger.NULL;
+  /**
+   * Prevent the creation of instances of this class.
+   */
+  AnalysisEngine() : super() {
+  }
+  /**
+   * Create a new context in which analysis can be performed.
+   * @return the analysis context that was created
+   */
+  AnalysisContext createAnalysisContext() => new AnalysisContextImpl();
+  /**
+   * Return the logger that should receive information about errors within the analysis engine.
+   * @return the logger that should receive information about errors within the analysis engine
+   */
+  Logger get logger => _logger;
+  /**
+   * Set the logger that should receive information about errors within the analysis engine to the
+   * given logger.
+   * @param logger the logger that should receive information about errors within the analysis
+   * engine
+   */
+  void set logger(Logger logger2) {
+    this._logger = logger2 == null ? Logger.NULL : logger2;
+  }
+}
+/**
+ * The interface {@code AnalysisContext} defines the behavior of objects that represent a context in
+ * which analysis can be performed. The context includes such information as the version of the SDK
+ * being analyzed against as well as the package-root used to resolve 'package:' URI's. This
+ * information is included indirectly through the {@link SourceFactory source factory}.
+ * <p>
+ * Analysis engine allows for having more than one context. This can be used, for example, to
+ * perform one analysis based on the state of files on disk and a separate analysis based on the
+ * state of those files in open editors. It can also be used to perform an analysis based on a
+ * proposed future state, such as after a refactoring.
+ */
+abstract class AnalysisContext {
+  /**
+   * Clear any cached information that is dependent on resolution. This method should be invoked if
+   * the assumptions used by resolution have changed but the contents of the file have not changed.
+   * Use {@link #sourceChanged(Source)} and {@link #sourcesDeleted(SourceContainer)} to indicate
+   * when the contents of a file or files have changed.
+   */
+  void clearResolution();
+  /**
+   * Call this method when this context is no longer going to be used. At this point, the receiver
+   * may choose to push some of its information back into the global cache for consumption by
+   * another context for performance.
+   */
+  void discard();
+  /**
+   * Create a new context in which analysis can be performed. Any sources in the specified directory
+   * in the receiver will be removed from the receiver and added to the newly created context.
+   * @param directory the directory (not {@code null}) containing sources that should be removed
+   * from the receiver and added to the returned context
+   * @return the analysis context that was created (not {@code null})
+   */
+  AnalysisContext extractAnalysisContext(SourceContainer container);
+  /**
+   * Answer the collection of sources that have been added to the receiver via{@link #sourceAvailable(Source)} and not removed from the receiver via{@link #sourceDeleted(Source)} or {@link #sourcesDeleted(SourceContainer)}.
+   * @return a collection of sources (not {@code null}, contains no {@code null}s)
+   */
+  Collection<Source> get availableSources;
+  /**
+   * Return the element referenced by the given location.
+   * @param location the reference describing the element to be returned
+   * @return the element referenced by the given location
+   */
+  Element getElement(ElementLocation location);
+  /**
+   * Return an array containing all of the errors associated with the given source.
+   * @param source the source whose errors are to be returned
+   * @return all of the errors associated with the given source
+   * @throws AnalysisException if the errors could not be determined because the analysis could not
+   * be performed
+   */
+  List<AnalysisError> getErrors(Source source);
+  /**
+   * Parse and build an element model for the HTML file defined by the given source.
+   * @param source the source defining the HTML file whose element model is to be returned
+   * @return the element model corresponding to the HTML file defined by the given source
+   */
+  HtmlElement getHtmlElement(Source source);
+  /**
+   * Return the kind of the given source if it is already known, or {@code null} if the kind is not
+   * already known.
+   * @param source the source whose kind is to be returned
+   * @return the kind of the given source
+   * @see #getOrComputeKindOf(Source)
+   */
+  SourceKind getKnownKindOf(Source source);
+  /**
+   * Return the element model corresponding to the library defined by the given source. If the
+   * element model does not yet exist it will be created. The process of creating an element model
+   * for a library can long-running, depending on the size of the library and the number of
+   * libraries that are imported into it that also need to have a model built for them.
+   * @param source the source defining the library whose element model is to be returned
+   * @return the element model corresponding to the library defined by the given source or{@code null} if the element model could not be determined because the analysis could
+   * not be performed
+   */
+  LibraryElement getLibraryElement(Source source);
+  /**
+   * Return the element model corresponding to the library defined by the given source, or{@code null} if the element model does not yet exist.
+   * @param source the source defining the library whose element model is to be returned
+   * @return the element model corresponding to the library defined by the given source
+   */
+  LibraryElement getLibraryElementOrNull(Source source);
+  /**
+   * Return the kind of the given source, computing it's kind if it is not already known.
+   * @param source the source whose kind is to be returned
+   * @return the kind of the given source
+   * @see #getKnownKindOf(Source)
+   */
+  SourceKind getOrComputeKindOf(Source source);
+  /**
+   * Return an array containing all of the parsing errors associated with the given source.
+   * @param source the source whose errors are to be returned
+   * @return all of the parsing errors associated with the given source
+   * @throws AnalysisException if the errors could not be determined because the analysis could not
+   * be performed
+   */
+  List<AnalysisError> getParsingErrors(Source source);
+  /**
+   * Return an array containing all of the resolution errors associated with the given source.
+   * @param source the source whose errors are to be returned
+   * @return all of the resolution errors associated with the given source
+   * @throws AnalysisException if the errors could not be determined because the analysis could not
+   * be performed
+   */
+  List<AnalysisError> getResolutionErrors(Source source);
+  /**
+   * Return the source factory used to create the sources that can be analyzed in this context.
+   * @return the source factory used to create the sources that can be analyzed in this context
+   */
+  SourceFactory get sourceFactory;
+  /**
+   * Add the sources contained in the specified context to the receiver's collection of sources.
+   * This method is called when an existing context's pubspec has been removed, and the contained
+   * sources should be reanalyzed as part of the receiver.
+   * @param context the context being merged (not {@code null})
+   */
+  void mergeAnalysisContext(AnalysisContext context);
+  /**
+   * Parse a single source to produce an AST structure. The resulting AST structure may or may not
+   * be resolved, and may have a slightly different structure depending upon whether it is resolved.
+   * @param source the source to be parsed
+   * @return the AST structure representing the content of the source
+   * @throws AnalysisException if the analysis could not be performed
+   */
+  CompilationUnit parse(Source source);
+  /**
+   * Parse and resolve a single source within the given context to produce a fully resolved AST.
+   * @param source the source to be parsed and resolved
+   * @param library the library defining the context in which the source file is to be resolved
+   * @return the result of resolving the AST structure representing the content of the source
+   * @throws AnalysisException if the analysis could not be performed
+   */
+  CompilationUnit resolve(Source source, LibraryElement library);
+  /**
+   * Scan a single source to produce a token stream.
+   * @param source the source to be scanned
+   * @param errorListener the listener to which errors should be reported
+   * @return the head of the token stream representing the content of the source
+   * @throws AnalysisException if the analysis could not be performed
+   */
+  Token scan(Source source, AnalysisErrorListener errorListener);
+  /**
+   * Set the source factory used to create the sources that can be analyzed in this context to the
+   * given source factory.
+   * @param sourceFactory the source factory used to create the sources that can be analyzed in this
+   * context
+   */
+  void set sourceFactory(SourceFactory sourceFactory4);
+  /**
+   * Cache the fact that content for the given source is now available, is of interest to the
+   * client, and should be analyzed. Do not modify or discard any information about this source that
+   * is already cached.
+   * @param source the source that is now available
+   */
+  void sourceAvailable(Source source);
+  /**
+   * Respond to the fact that the content of the given source has changed by removing any cached
+   * information that might now be out-of-date.
+   * @param source the source whose content has changed
+   */
+  void sourceChanged(Source source);
+  /**
+   * Respond to the fact that the given source has been deleted and should no longer be analyzed by
+   * removing any cached information that might now be out-of-date.
+   * @param source the source that was deleted
+   */
+  void sourceDeleted(Source source);
+  /**
+   * Discard cached information for all files in the specified source container.
+   * @param container the source container that was deleted (not {@code null})
+   */
+  void sourcesDeleted(SourceContainer container);
+  /**
+   * Given a collection of sources with content that has changed, return an {@link Iterable}identifying the sources that need to be resolved.
+   * @param changedSources an array of sources (not {@code null}, contains no {@code null}s)
+   * @return An iterable returning the sources to be resolved
+   */
+  Iterable<Source> sourcesToResolve(List<Source> changedSources);
+}
+/**
+ * Instances of the class {@code AnalysisException} represent an exception that occurred during the
+ * analysis of one or more sources.
+ */
+class AnalysisException extends JavaException {
+  /**
+   * Initialize a newly created exception.
+   */
+  AnalysisException() : super() {
+    _jtd_constructor_117_impl();
+  }
+  _jtd_constructor_117_impl() {
+  }
+  /**
+   * Initialize a newly created exception to have the given message.
+   * @param message the message associated with the exception
+   */
+  AnalysisException.con1(String message) : super(message) {
+    _jtd_constructor_118_impl(message);
+  }
+  _jtd_constructor_118_impl(String message) {
+  }
+  /**
+   * Initialize a newly created exception to have the given message and cause.
+   * @param message the message associated with the exception
+   * @param cause the underlying exception that caused this exception
+   */
+  AnalysisException.con2(String message, Exception cause) : super(message, cause) {
+    _jtd_constructor_119_impl(message, cause);
+  }
+  _jtd_constructor_119_impl(String message, Exception cause) {
+  }
+  /**
+   * Initialize a newly created exception to have the given cause.
+   * @param cause the underlying exception that caused this exception
+   */
+  AnalysisException.con3(Exception cause) : super.withCause(cause) {
+    _jtd_constructor_120_impl(cause);
+  }
+  _jtd_constructor_120_impl(Exception cause) {
+  }
+}
+/**
+ * Instances of the class {@code AnalysisContextImpl} implement an {@link AnalysisContext analysis
+ * context}.
+ */
+class AnalysisContextImpl implements AnalysisContext {
+  /**
+   * The source factory used to create the sources that can be analyzed in this context.
+   */
+  SourceFactory _sourceFactory;
+  /**
+   * A cache mapping sources to the compilation units that were produced for the contents of the
+   * source.
+   */
+  Map<Source, CompilationUnit> _parseCache = new Map<Source, CompilationUnit>();
+  /**
+   * A cache mapping sources (of the defining compilation units of libraries) to the library
+   * elements for those libraries.
+   */
+  Map<Source, LibraryElement> _libraryElementCache = new Map<Source, LibraryElement>();
+  /**
+   * A cache mapping sources (of the defining compilation units of libraries) to the public
+   * namespace for that library.
+   */
+  Map<Source, Namespace> _publicNamespaceCache = new Map<Source, Namespace>();
+  /**
+   * A cache of the available sources of interest to the client. Sources are added to this
+   * collection via {@link #sourceAvailable(Source)} and removed from this collection via{@link #sourceDeleted(Source)} and {@link #directoryDeleted(File)}
+   */
+  Set<Source> _availableSources = new Set<Source>();
+  /**
+   * The object used to synchronize access to all of the caches.
+   */
+  Object _cacheLock = new Object();
+  /**
+   * The suffix used by sources that contain Dart.
+   */
+  static String _DART_SUFFIX = ".dart";
+  /**
+   * The suffix used by sources that contain HTML.
+   */
+  static String _HTML_SUFFIX = ".html";
+  /**
+   * Initialize a newly created analysis context.
+   */
+  AnalysisContextImpl() : super() {
+  }
+  void clearResolution() {
+    {
+      _parseCache.clear();
+      _libraryElementCache.clear();
+      _publicNamespaceCache.clear();
+    }
+  }
+  void discard() {
+    {
+      _parseCache.clear();
+      _libraryElementCache.clear();
+      _publicNamespaceCache.clear();
+      _availableSources.clear();
+    }
+  }
+  AnalysisContext extractAnalysisContext(SourceContainer container) {
+    AnalysisContext newContext = AnalysisEngine.instance.createAnalysisContext();
+    {
+      JavaIterator<Source> iter = new JavaIterator(_availableSources);
+      while (iter.hasNext) {
+        Source source = iter.next();
+        if (container.contains(source)) {
+          iter.remove();
+          newContext.sourceAvailable(source);
+        }
+      }
+    }
+    return newContext;
+  }
+  Collection<Source> get availableSources {
+    {
+      return new List<Source>.from(_availableSources);
+    }
+  }
+  Element getElement(ElementLocation location) {
+    throw new UnsupportedOperationException();
+  }
+  List<AnalysisError> getErrors(Source source) {
+    throw new UnsupportedOperationException();
+  }
+  HtmlElement getHtmlElement(Source source) {
+    throw new UnsupportedOperationException();
+  }
+  SourceKind getKnownKindOf(Source source) {
+    if (source.fullName.endsWith(_HTML_SUFFIX)) {
+      return SourceKind.HTML;
+    }
+    if (!source.fullName.endsWith(_DART_SUFFIX)) {
+      return SourceKind.UNKNOWN;
+    }
+    {
+      if (_libraryElementCache.containsKey(source)) {
+        return SourceKind.LIBRARY;
+      }
+      CompilationUnit unit = _parseCache[source];
+      if (unit != null && hasPartOfDirective(unit)) {
+        return SourceKind.PART;
+      }
+    }
+    return null;
+  }
+  LibraryElement getLibraryElement(Source source) {
+    {
+      LibraryElement element = _libraryElementCache[source];
+      if (element == null) {
+        RecordingErrorListener listener = new RecordingErrorListener();
+        LibraryResolver resolver = new LibraryResolver(this, listener);
+        try {
+          element = resolver.resolveLibrary(source, true);
+        } on AnalysisException catch (exception) {
+          AnalysisEngine.instance.logger.logError2("Could not resolve the library ${source.fullName}", exception);
+        }
+      }
+      return element;
+    }
+  }
+  /**
+   * Return the element model corresponding to the library defined by the given source, or{@code null} if the element model does not yet exist.
+   * @param source the source defining the library whose element model is to be returned
+   * @return the element model corresponding to the library defined by the given source
+   */
+  LibraryElement getLibraryElementOrNull(Source source) {
+    {
+      return _libraryElementCache[source];
+    }
+  }
+  SourceKind getOrComputeKindOf(Source source) {
+    SourceKind kind = getKnownKindOf(source);
+    if (kind != null) {
+      return kind;
+    }
+    try {
+      if (hasPartOfDirective(parse(source))) {
+        return SourceKind.PART;
+      }
+    } on AnalysisException catch (exception) {
+      return SourceKind.UNKNOWN;
+    }
+    return SourceKind.LIBRARY;
+  }
+  List<AnalysisError> getParsingErrors(Source source) {
+    throw new UnsupportedOperationException();
+  }
+  /**
+   * Return a namespace containing mappings for all of the public names defined by the given
+   * library.
+   * @param library the library whose public namespace is to be returned
+   * @return the public namespace of the given library
+   */
+  Namespace getPublicNamespace(LibraryElement library) {
+    Source source7 = library.definingCompilationUnit.source;
+    {
+      Namespace namespace = _publicNamespaceCache[source7];
+      if (namespace == null) {
+        NamespaceBuilder builder = new NamespaceBuilder();
+        namespace = builder.createPublicNamespace(library);
+        _publicNamespaceCache[source7] = namespace;
+      }
+      return namespace;
+    }
+  }
+  /**
+   * Return a namespace containing mappings for all of the public names defined by the library
+   * defined by the given source.
+   * @param source the source defining the library whose public namespace is to be returned
+   * @return the public namespace corresponding to the library defined by the given source
+   */
+  Namespace getPublicNamespace2(Source source) {
+    {
+      Namespace namespace = _publicNamespaceCache[source];
+      if (namespace == null) {
+        LibraryElement library = getLibraryElement(source);
+        if (library == null) {
+          return null;
+        }
+        NamespaceBuilder builder = new NamespaceBuilder();
+        namespace = builder.createPublicNamespace(library);
+        _publicNamespaceCache[source] = namespace;
+      }
+      return namespace;
+    }
+  }
+  List<AnalysisError> getResolutionErrors(Source source) {
+    throw new UnsupportedOperationException();
+  }
+  SourceFactory get sourceFactory => _sourceFactory;
+  void mergeAnalysisContext(AnalysisContext context) {
+    {
+      _availableSources.addAll(context.availableSources);
+    }
+  }
+  CompilationUnit parse(Source source) {
+    {
+      CompilationUnit unit = _parseCache[source];
+      if (unit == null) {
+        RecordingErrorListener errorListener = new RecordingErrorListener();
+        Token token = scan(source, errorListener);
+        Parser parser = new Parser(source, errorListener);
+        unit = parser.parseCompilationUnit(token);
+        unit.parsingErrors = errorListener.errors;
+        _parseCache[source] = unit;
+      }
+      return unit;
+    }
+  }
+  CompilationUnit parse2(Source source, AnalysisErrorListener errorListener) {
+    {
+      CompilationUnit unit = _parseCache[source];
+      if (unit == null) {
+        Token token = scan(source, errorListener);
+        Parser parser = new Parser(source, errorListener);
+        unit = parser.parseCompilationUnit(token);
+        _parseCache[source] = unit;
+      }
+      return unit;
+    }
+  }
+  /**
+   * Given a table mapping the source for the libraries represented by the corresponding elements to
+   * the elements representing the libraries, record those mappings.
+   * @param elementMap a table mapping the source for the libraries represented by the elements to
+   * the elements representing the libraries
+   */
+  void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
+    {
+      javaMapPutAll(_libraryElementCache, elementMap);
+    }
+  }
+  CompilationUnit resolve(Source source, LibraryElement library) => parse(source);
+  Token scan(Source source, AnalysisErrorListener errorListener) {
+    List<Token> tokens = new List<Token>.fixedLength(1);
+    Source_ContentReceiver receiver = new Source_ContentReceiver_1(source, errorListener, tokens);
+    try {
+      source.getContents(receiver);
+    } on JavaException catch (exception) {
+    }
+    return tokens[0];
+  }
+  void set sourceFactory(SourceFactory sourceFactory2) {
+    this._sourceFactory = sourceFactory2;
+  }
+  void sourceAvailable(Source source) {
+    {
+      javaSetAdd(_availableSources, source);
+    }
+  }
+  void sourceChanged(Source source) {
+    {
+      _parseCache.remove(source);
+      _libraryElementCache.remove(source);
+      _publicNamespaceCache.remove(source);
+    }
+  }
+  void sourceDeleted(Source source) {
+    {
+      _availableSources.remove(source);
+      sourceChanged(source);
+    }
+  }
+  void sourcesDeleted(SourceContainer container) {
+    {
+      _parseCache.clear();
+      _libraryElementCache.clear();
+      _publicNamespaceCache.clear();
+      JavaIterator<Source> iter = new JavaIterator(_availableSources);
+      while (iter.hasNext) {
+        if (container.contains(iter.next())) {
+          iter.remove();
+        }
+      }
+    }
+  }
+  Iterable<Source> sourcesToResolve(List<Source> changedSources) => JavaArrays.asList(changedSources);
+  /**
+   * Return {@code true} if the given compilation unit has a part-of directive.
+   * @param unit the compilation unit being tested
+   * @return {@code true} if the compilation unit has a part-of directive
+   */
+  bool hasPartOfDirective(CompilationUnit unit) {
+    for (Directive directive in unit.directives) {
+      if (directive is PartOfDirective) {
+        return true;
+      }
+    }
+    return false;
+  }
+}
+class Source_ContentReceiver_1 implements Source_ContentReceiver {
+  Source source;
+  AnalysisErrorListener errorListener;
+  List<Token> tokens;
+  Source_ContentReceiver_1(this.source, this.errorListener, this.tokens);
+  accept(CharBuffer contents) {
+    CharBufferScanner scanner = new CharBufferScanner(source, contents, errorListener);
+    tokens[0] = scanner.tokenize();
+  }
+  void accept2(String contents) {
+    StringScanner scanner = new StringScanner(source, contents, errorListener);
+    tokens[0] = scanner.tokenize();
+  }
+}
+/**
+ * Instances of the class {@code RecordingErrorListener} implement an error listener that will
+ * record the errors that are reported to it in a way that is appropriate for caching those errors
+ * within an analysis context.
+ */
+class RecordingErrorListener implements AnalysisErrorListener {
+  /**
+   * A list containing the errors that were collected.
+   */
+  List<AnalysisError> _errors = null;
+  /**
+   * Answer the errors collected by the listener.
+   * @return an array of errors (not {@code null}, contains no {@code null}s)
+   */
+  List<AnalysisError> get errors => _errors != null ? new List.from(_errors) : AnalysisError.NO_ERRORS;
+  void onError(AnalysisError event) {
+    if (_errors == null) {
+      _errors = new List<AnalysisError>();
+    }
+    _errors.add(event);
+  }
+}
+/**
+ * The interface {@code Logger} defines the behavior of objects that can be used to receive
+ * information about errors within the analysis engine. Implementations usually write this
+ * information to a file, but can also record the information for later use (such as during testing)
+ * or even ignore the information.
+ */
+abstract class Logger {
+  static Logger NULL = new Logger_NullLogger();
+  /**
+   * Log the given message as an error.
+   * @param message an explanation of why the error occurred or what it means
+   */
+  void logError(String message);
+  /**
+   * Log the given exception as one representing an error.
+   * @param message an explanation of why the error occurred or what it means
+   * @param exception the exception being logged
+   */
+  void logError2(String message, Exception exception);
+  /**
+   * Log the given exception as one representing an error.
+   * @param exception the exception being logged
+   */
+  void logError3(Exception exception);
+  /**
+   * Log the given informational message.
+   * @param message an explanation of why the error occurred or what it means
+   * @param exception the exception being logged
+   */
+  void logInformation(String message);
+  /**
+   * Log the given exception as one representing an informational message.
+   * @param message an explanation of why the error occurred or what it means
+   * @param exception the exception being logged
+   */
+  void logInformation2(String message, Exception exception);
+}
+/**
+ * Implementation of {@link Logger} that does nothing.
+ */
+class Logger_NullLogger implements Logger {
+  void logError(String message) {
+  }
+  void logError2(String message, Exception exception) {
+  }
+  void logError3(Exception exception) {
+  }
+  void logInformation(String message) {
+  }
+  void logInformation2(String message, Exception exception) {
+  }
+}
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/lib/src/generated/error.dart b/pkg/analyzer-experimental/lib/src/generated/error.dart
index b888255..17a0466 100644
--- a/pkg/analyzer-experimental/lib/src/generated/error.dart
+++ b/pkg/analyzer-experimental/lib/src/generated/error.dart
@@ -149,13 +149,13 @@
    * @param errorCode the error code to be associated with this error
    * @param arguments the arguments used to build the error message
    */
-  AnalysisError.con1(Source source, ErrorCode errorCode, List<Object> arguments) {
-    _jtd_constructor_117_impl(source, errorCode, arguments);
+  AnalysisError.con1(Source source2, ErrorCode errorCode2, List<Object> arguments) {
+    _jtd_constructor_122_impl(source2, errorCode2, arguments);
   }
-  _jtd_constructor_117_impl(Source source, ErrorCode errorCode, List<Object> arguments) {
-    this._source = source;
-    this._errorCode = errorCode;
-    this._message = JavaString.format(errorCode.message, arguments);
+  _jtd_constructor_122_impl(Source source2, ErrorCode errorCode2, List<Object> arguments) {
+    this._source = source2;
+    this._errorCode = errorCode2;
+    this._message = JavaString.format(errorCode2.message, arguments);
   }
   /**
    * Initialize a newly created analysis error for the specified source at the given location.
@@ -165,15 +165,15 @@
    * @param errorCode the error code to be associated with this error
    * @param arguments the arguments used to build the error message
    */
-  AnalysisError.con2(Source source, int offset, int length, ErrorCode errorCode, List<Object> arguments) {
-    _jtd_constructor_118_impl(source, offset, length, errorCode, arguments);
+  AnalysisError.con2(Source source3, int offset2, int length11, ErrorCode errorCode3, List<Object> arguments) {
+    _jtd_constructor_123_impl(source3, offset2, length11, errorCode3, arguments);
   }
-  _jtd_constructor_118_impl(Source source, int offset, int length, ErrorCode errorCode, List<Object> arguments) {
-    this._source = source;
-    this._offset = offset;
-    this._length = length;
-    this._errorCode = errorCode;
-    this._message = JavaString.format(errorCode.message, arguments);
+  _jtd_constructor_123_impl(Source source3, int offset2, int length11, ErrorCode errorCode3, List<Object> arguments) {
+    this._source = source3;
+    this._offset = offset2;
+    this._length = length11;
+    this._errorCode = errorCode3;
+    this._message = JavaString.format(errorCode3.message, arguments);
   }
   /**
    * Return the error code associated with the error.
@@ -212,8 +212,8 @@
    * Set the source in which the error occurred to the given source.
    * @param source the source in which the error occurred
    */
-  void set source2(Source source) {
-    this._source = source;
+  void set source(Source source4) {
+    this._source = source4;
   }
   String toString() {
     StringBuffer builder = new StringBuffer();
diff --git a/pkg/analyzer-experimental/lib/src/generated/instrumentation.dart b/pkg/analyzer-experimental/lib/src/generated/instrumentation.dart
index 6083629..fbf9994 100644
--- a/pkg/analyzer-experimental/lib/src/generated/instrumentation.dart
+++ b/pkg/analyzer-experimental/lib/src/generated/instrumentation.dart
@@ -116,7 +116,7 @@
    * An instrumentation logger that can be used when no other instrumentation logger has been
    * configured. This logger will silently ignore all data and logging requests.
    */
-  static InstrumentationLogger _NULL_LOGGER = new InstrumentationLogger_2();
+  static InstrumentationLogger _NULL_LOGGER = new InstrumentationLogger_5();
   /**
    * The current instrumentation logger.
    */
@@ -162,8 +162,8 @@
    * Set the logger that should receive instrumentation information to the given logger.
    * @param logger the logger that should receive instrumentation information
    */
-  static void set logger(InstrumentationLogger logger) {
-    _CURRENT_LOGGER = logger == null ? Instrumentation._NULL_LOGGER : logger;
+  static void set logger(InstrumentationLogger logger3) {
+    _CURRENT_LOGGER = logger3 == null ? _NULL_LOGGER : logger3;
   }
   /**
    * Prevent the creation of instances of this class
@@ -171,15 +171,15 @@
   Instrumentation() {
   }
 }
-class InstrumentationLogger_2 implements InstrumentationLogger {
+class InstrumentationLogger_5 implements InstrumentationLogger {
   /**
    * An operation builder that will silently ignore all data and logging requests.
    */
-  OperationBuilder _NULL_BUILDER = new OperationBuilder_3();
+  OperationBuilder _NULL_BUILDER = new OperationBuilder_6();
   OperationBuilder createMetric(String name, int time) => _NULL_BUILDER;
   OperationBuilder createOperation(String name, int time) => _NULL_BUILDER;
 }
-class OperationBuilder_3 implements OperationBuilder {
+class OperationBuilder_6 implements OperationBuilder {
   void log() {
   }
   OperationBuilder with2(String name, AsyncValue valueGenerator) => this;
diff --git a/pkg/analyzer-experimental/lib/src/generated/java_core.dart b/pkg/analyzer-experimental/lib/src/generated/java_core.dart
index 25c8862..5d49598 100644
--- a/pkg/analyzer-experimental/lib/src/generated/java_core.dart
+++ b/pkg/analyzer-experimental/lib/src/generated/java_core.dart
@@ -1,11 +1,30 @@
 library java.core;
 
 import "dart:math" as math;
+import "dart:io";
+import "dart:uri";
 
 class System {
+  static final String pathSeparator = Platform.pathSeparator;
+  static final int pathSeparatorChar = Platform.pathSeparator.codeUnitAt(0);
+
   static int currentTimeMillis() {
-    return (new Date.now()).millisecondsSinceEpoch;
+    return (new DateTime.now()).millisecondsSinceEpoch;
   }
+  static String getProperty(String name) {
+    if (name == 'os.name') {
+      return Platform.operatingSystem;
+    }
+    if (name == 'line.separator') {
+      if (Platform.operatingSystem == 'windows') {
+        return '\r\n';
+      }
+      return '\n';
+    }
+    return null;
+  }
+  static String getenv(String name) => Platform.environment[name];
+
 }
 
 /**
@@ -20,7 +39,17 @@
     return true;
   }
   String oTypeName = o.runtimeType.toString();
-  if (oTypeName == "${t.toString()}Impl") {
+  String tTypeName = t.toString();
+  if (oTypeName == tTypeName) {
+    return true;
+  }
+  if (oTypeName == "${tTypeName}Impl") {
+    return true;
+  }
+  if (oTypeName.startsWith("_HashMap") && tTypeName == "Map") {
+    return true;
+  }
+  if (oTypeName.startsWith("List") && tTypeName == "List") {
     return true;
   }
   return false;
@@ -45,10 +74,11 @@
     }
     int result = 1;
     for (var element in a) {
-      result = 31 * result + (element == null ? 0 : element.hashCode());
+      result = 31 * result + (element == null ? 0 : element.hashCode);
     }
     return result;
   }
+  static List asList(List list) => list;
 }
 
 class Character {
@@ -80,7 +110,7 @@
   final String _content;
   CharBuffer(this._content);
   static CharBuffer wrap(String content) => new CharBuffer(content);
-  int charAt(int index) => _content.charCodeAt(index);
+  int charAt(int index) => _content.codeUnitAt(index);
   int length() => _content.length;
   String subSequence(int start, int end) => _content.substring(start, end);
 }
@@ -99,7 +129,7 @@
   bool markFound = false;
   int argIndex = 0;
   for (int i = 0; i < fmt.length; i++) {
-    int c = fmt.charCodeAt(i);
+    int c = fmt.codeUnitAt(i);
     if (c == 0x25) {
       if (markFound) {
         sb.addCharCode(c);
@@ -178,9 +208,17 @@
   String toString() => "RuntimeException";
 }
 
+class JavaException implements Exception {
+  final String message;
+  final Exception e;
+  JavaException([this.message = "", this.e = null]);
+  JavaException.withCause(this.e) : message = null;
+  String toString() => "JavaException: $message $e";
+}
+
 class IllegalArgumentException implements Exception {
   final String message;
-  const IllegalArgumentException([this.message = ""]);
+  const IllegalArgumentException([this.message = "", Exception e = null]);
   String toString() => "IllegalStateException: $message";
 }
 
@@ -198,6 +236,14 @@
   String toString() => "NumberFormatException";
 }
 
+class URISyntaxException implements Exception {
+  String toString() => "URISyntaxException";
+}
+
+class IOException implements Exception {
+  String toString() => "IOException";
+}
+
 class ListWrapper<E> extends Collection<E> implements List<E> {
   List<E> elements = new List<E>();
 
@@ -276,6 +322,42 @@
   }
 }
 
+class JavaIterator<E> {
+  Collection<E> _collection;
+  List<E> _elements = new List<E>();
+  int _coPos = 0;
+  int _elPos = 0;
+  E _current = null;
+  JavaIterator(this._collection) {
+    Iterator iterator = _collection.iterator;
+    while (iterator.moveNext()) {
+      _elements.add(iterator.current);
+    }
+  }
+
+  bool get hasNext {
+    return _elPos < _elements.length;
+  }
+
+  E next() {
+    _current = _elements[_elPos];
+    _coPos++;
+    _elPos++;
+    return _current;
+  }
+
+  void remove() {
+    if (_collection is List) {
+      _coPos--;
+      (_collection as List).remove(_coPos);
+    } else if (_collection is Set) {
+      _collection.remove(_current);
+    } else {
+      throw new StateError("Unsupported collection ${_collection.runtimeType}");
+    }
+  }
+}
+
 class MapEntry<K, V> {
   K _key;
   V _value;
@@ -298,4 +380,28 @@
     return true;
   }
   return false;
-}
\ No newline at end of file
+}
+
+void javaMapPutAll(Map target, Map source) {
+  source.forEach((k, v) {
+    target[k] = v;
+  });
+}
+
+File newRelativeFile(File base, String child) {
+  var childPath = new Path(base.fullPathSync()).join(new Path(child));
+  return new File.fromPath(childPath);
+}
+
+File newFileFromUri(Uri uri) {
+  return new File(uri.path);
+}
+
+File getAbsoluteFile(File file) {
+  var path = file.fullPathSync();
+  return new File(path);
+}
+
+Uri newUriFromFile(File file) {
+  return new Uri.fromComponents(path: file.fullPathSync());
+}
diff --git a/pkg/analyzer-experimental/lib/src/generated/java_engine.dart b/pkg/analyzer-experimental/lib/src/generated/java_engine.dart
index 9a0c265..9254fdc 100644
--- a/pkg/analyzer-experimental/lib/src/generated/java_engine.dart
+++ b/pkg/analyzer-experimental/lib/src/generated/java_engine.dart
@@ -1,48 +1,56 @@
 library java.engine;
 
+import "dart:io";
 import "java_core.dart";
 import "source.dart";
 import "error.dart";
 import "ast.dart";
 import "element.dart";
 
-class AnalysisException implements Exception {
-  String toString() => "AnalysisException";
-}
+//class AnalysisException implements Exception {
+//  String toString() => "AnalysisException";
+//}
 
-class AnalysisEngine {
-  static getInstance() {
-    throw new UnsupportedOperationException();
-  }
-}
+//class AnalysisEngine {
+//  static getInstance() {
+//    throw new UnsupportedOperationException();
+//  }
+//}
 
-class AnalysisContext {
-  Element getElement(ElementLocation location) {
-    throw new UnsupportedOperationException();
-  }
-}
+//class AnalysisContext {
+//  Element getElement(ElementLocation location) {
+//    throw new UnsupportedOperationException();
+//  }
+//}
 
-class AnalysisContextImpl extends AnalysisContext {
-  getSourceFactory() {
-    throw new UnsupportedOperationException();
-  }
-  LibraryElement getLibraryElementOrNull(Source source) {
-    return null;
-  }
-  LibraryElement getLibraryElement(Source source) {
-    throw new UnsupportedOperationException();
-  }
-  void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
-    throw new UnsupportedOperationException();
-  }
-  getPublicNamespace(LibraryElement library) {
-    throw new UnsupportedOperationException();
-  }
-  CompilationUnit parse(Source source, AnalysisErrorListener errorListener) {
-    throw new UnsupportedOperationException();
-  }
-}
+//class AnalysisContextImpl extends AnalysisContext {
+//  getSourceFactory() {
+//    throw new UnsupportedOperationException();
+//  }
+//  LibraryElement getLibraryElementOrNull(Source source) {
+//    return null;
+//  }
+//  LibraryElement getLibraryElement(Source source) {
+//    throw new UnsupportedOperationException();
+//  }
+//  void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
+//    throw new UnsupportedOperationException();
+//  }
+//  getPublicNamespace(LibraryElement library) {
+//    throw new UnsupportedOperationException();
+//  }
+//  CompilationUnit parse(Source source, AnalysisErrorListener errorListener) {
+//    throw new UnsupportedOperationException();
+//  }
+//}
 
 class StringUtilities {
   static List<String> EMPTY_ARRAY = new List.fixedLength(0);
 }
+
+File createFile(String path) => new File(path);
+
+class OSUtilities {
+  static bool isWindows() => Platform.operatingSystem == 'windows';
+  static bool isMac() => Platform.operatingSystem == 'macos';
+}
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/lib/src/generated/java_junit.dart b/pkg/analyzer-experimental/lib/src/generated/java_junit.dart
index 62879bc..8d284eb 100644
--- a/pkg/analyzer-experimental/lib/src/generated/java_junit.dart
+++ b/pkg/analyzer-experimental/lib/src/generated/java_junit.dart
@@ -34,6 +34,9 @@
   static void assertEqualsMsg(String msg, expected, actual) {
     expect(actual, equalsMsg(msg, expected));
   }
+  static void assertSame(expected, actual) {
+    expect(actual, same(expected));
+  }
 }
 
 runJUnitTest(testInstance, Function testFunction) {
diff --git a/pkg/analyzer-experimental/lib/src/generated/parser.dart b/pkg/analyzer-experimental/lib/src/generated/parser.dart
index 007f82f..1c3f211 100644
--- a/pkg/analyzer-experimental/lib/src/generated/parser.dart
+++ b/pkg/analyzer-experimental/lib/src/generated/parser.dart
@@ -161,50 +161,50 @@
    * Set the token representing the keyword 'abstract' to the given token.
    * @param abstractKeyword the token representing the keyword 'abstract'
    */
-  void set abstractKeyword4(Token abstractKeyword) {
-    this._abstractKeyword = abstractKeyword;
+  void set abstractKeyword(Token abstractKeyword4) {
+    this._abstractKeyword = abstractKeyword4;
   }
   /**
    * Set the token representing the keyword 'const' to the given token.
    * @param constKeyword the token representing the keyword 'const'
    */
-  void set constKeyword3(Token constKeyword) {
-    this._constKeyword = constKeyword;
+  void set constKeyword(Token constKeyword3) {
+    this._constKeyword = constKeyword3;
   }
   /**
    * Set the token representing the keyword 'external' to the given token.
    * @param externalKeyword the token representing the keyword 'external'
    */
-  void set externalKeyword5(Token externalKeyword) {
-    this._externalKeyword = externalKeyword;
+  void set externalKeyword(Token externalKeyword5) {
+    this._externalKeyword = externalKeyword5;
   }
   /**
    * Set the token representing the keyword 'factory' to the given token.
    * @param factoryKeyword the token representing the keyword 'factory'
    */
-  void set factoryKeyword3(Token factoryKeyword) {
-    this._factoryKeyword = factoryKeyword;
+  void set factoryKeyword(Token factoryKeyword3) {
+    this._factoryKeyword = factoryKeyword3;
   }
   /**
    * Set the token representing the keyword 'final' to the given token.
    * @param finalKeyword the token representing the keyword 'final'
    */
-  void set finalKeyword2(Token finalKeyword) {
-    this._finalKeyword = finalKeyword;
+  void set finalKeyword(Token finalKeyword2) {
+    this._finalKeyword = finalKeyword2;
   }
   /**
    * Set the token representing the keyword 'static' to the given token.
    * @param staticKeyword the token representing the keyword 'static'
    */
-  void set staticKeyword2(Token staticKeyword) {
-    this._staticKeyword = staticKeyword;
+  void set staticKeyword(Token staticKeyword2) {
+    this._staticKeyword = staticKeyword2;
   }
   /**
    * Set the token representing the keyword 'var' to the given token.
    * @param varKeyword the token representing the keyword 'var'
    */
-  void set varKeyword2(Token varKeyword) {
-    this._varKeyword = varKeyword;
+  void set varKeyword(Token varKeyword2) {
+    this._varKeyword = varKeyword2;
   }
   String toString() {
     StringBuffer builder = new StringBuffer();
@@ -313,8 +313,8 @@
     _currentToken = token;
     return parseStatements2();
   }
-  void set currentToken(Token currentToken) {
-    this._currentToken = currentToken;
+  void set currentToken(Token currentToken2) {
+    this._currentToken = currentToken2;
   }
   /**
    * Advance to the next token in the token stream.
@@ -338,7 +338,7 @@
       return;
     }
     if (scalarValue < Character.MAX_VALUE) {
-      builder.addCharCode(scalarValue as int);
+      builder.addCharCode((scalarValue as int));
     } else {
       builder.add(Character.toChars(scalarValue));
     }
@@ -381,12 +381,12 @@
    * Create a synthetic identifier.
    * @return the synthetic identifier that was created
    */
-  SimpleIdentifier createSyntheticIdentifier() => new SimpleIdentifier(createSyntheticToken(TokenType.IDENTIFIER));
+  SimpleIdentifier createSyntheticIdentifier() => new SimpleIdentifier.full(createSyntheticToken(TokenType.IDENTIFIER));
   /**
    * Create a synthetic string literal.
    * @return the synthetic string literal that was created
    */
-  SimpleStringLiteral createSyntheticStringLiteral() => new SimpleStringLiteral(createSyntheticToken(TokenType.STRING), "");
+  SimpleStringLiteral createSyntheticStringLiteral() => new SimpleStringLiteral.full(createSyntheticToken(TokenType.STRING), "");
   /**
    * Create a synthetic token with the given type.
    * @return the synthetic token that was created
@@ -433,7 +433,7 @@
     if (matches5(type)) {
       return andAdvance;
     }
-    if (type == TokenType.SEMICOLON) {
+    if (identical(type, TokenType.SEMICOLON)) {
       reportError4(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [type.lexeme]);
     } else {
       reportError3(ParserErrorCode.EXPECTED_TOKEN, [type.lexeme]);
@@ -537,8 +537,8 @@
     if (token == null) {
       return false;
     }
-    TokenType type17 = token.type;
-    return type17 == TokenType.EQ || type17 == TokenType.COMMA || type17 == TokenType.SEMICOLON || matches3(token, Keyword.IN);
+    TokenType type15 = token.type;
+    return identical(type15, TokenType.EQ) || identical(type15, TokenType.COMMA) || identical(type15, TokenType.SEMICOLON) || matches3(token, Keyword.IN);
   }
   /**
    * Return {@code true} if the current token appears to be the beginning of a switch member.
@@ -549,9 +549,9 @@
     while (matches4(token, TokenType.IDENTIFIER) && matches4(token.next, TokenType.COLON)) {
       token = token.next.next;
     }
-    if (token.type == TokenType.KEYWORD) {
-      Keyword keyword28 = (token as KeywordToken).keyword;
-      return keyword28 == Keyword.CASE || keyword28 == Keyword.DEFAULT;
+    if (identical(token.type, TokenType.KEYWORD)) {
+      Keyword keyword27 = ((token as KeywordToken)).keyword;
+      return identical(keyword27, Keyword.CASE) || identical(keyword27, Keyword.DEFAULT);
     }
     return false;
   }
@@ -568,8 +568,8 @@
     int firstOffset = 2147483647;
     for (Token token in tokens) {
       if (token != null) {
-        int offset3 = token.offset;
-        if (offset3 < firstOffset) {
+        int offset4 = token.offset;
+        if (offset4 < firstOffset) {
           first = token;
         }
       }
@@ -587,21 +587,21 @@
    * @param identifier the identifier that can optionally appear in the current location
    * @return {@code true} if the current token matches the given identifier
    */
-  bool matches2(String identifier) => _currentToken.type == TokenType.IDENTIFIER && _currentToken.lexeme == identifier;
+  bool matches2(String identifier) => identical(_currentToken.type, TokenType.IDENTIFIER) && _currentToken.lexeme == identifier;
   /**
    * Return {@code true} if the given token matches the given keyword.
    * @param token the token being tested
    * @param keyword the keyword that is being tested for
    * @return {@code true} if the given token matches the given keyword
    */
-  bool matches3(Token token, Keyword keyword) => token.type == TokenType.KEYWORD && (token as KeywordToken).keyword == keyword;
+  bool matches3(Token token, Keyword keyword35) => identical(token.type, TokenType.KEYWORD) && identical(((token as KeywordToken)).keyword, keyword35);
   /**
    * Return {@code true} if the given token has the given type.
    * @param token the token being tested
    * @param type the type of token that is being tested for
    * @return {@code true} if the given token has the given type
    */
-  bool matches4(Token token, TokenType type) => token.type == type;
+  bool matches4(Token token, TokenType type24) => identical(token.type, type24);
   /**
    * Return {@code true} if the current token has the given type. Note that this method, unlike
    * other variants, will modify the token stream if possible to match a wider range of tokens. In
@@ -610,33 +610,33 @@
    * @param type the type of token that can optionally appear in the current location
    * @return {@code true} if the current token has the given type
    */
-  bool matches5(TokenType type) {
+  bool matches5(TokenType type25) {
     TokenType currentType = _currentToken.type;
-    if (currentType != type) {
-      if (type == TokenType.GT) {
-        if (currentType == TokenType.GT_GT) {
-          int offset4 = _currentToken.offset;
-          Token first = new Token(TokenType.GT, offset4);
-          Token second = new Token(TokenType.GT, offset4 + 1);
-          second.setNext(_currentToken.next);
-          first.setNext(second);
-          _currentToken.previous.setNext(first);
-          _currentToken = first;
-          return true;
-        } else if (currentType == TokenType.GT_EQ) {
+    if (currentType != type25) {
+      if (identical(type25, TokenType.GT)) {
+        if (identical(currentType, TokenType.GT_GT)) {
           int offset5 = _currentToken.offset;
           Token first = new Token(TokenType.GT, offset5);
-          Token second = new Token(TokenType.EQ, offset5 + 1);
+          Token second = new Token(TokenType.GT, offset5 + 1);
           second.setNext(_currentToken.next);
           first.setNext(second);
           _currentToken.previous.setNext(first);
           _currentToken = first;
           return true;
-        } else if (currentType == TokenType.GT_GT_EQ) {
+        } else if (identical(currentType, TokenType.GT_EQ)) {
           int offset6 = _currentToken.offset;
           Token first = new Token(TokenType.GT, offset6);
-          Token second = new Token(TokenType.GT, offset6 + 1);
-          Token third = new Token(TokenType.EQ, offset6 + 2);
+          Token second = new Token(TokenType.EQ, offset6 + 1);
+          second.setNext(_currentToken.next);
+          first.setNext(second);
+          _currentToken.previous.setNext(first);
+          _currentToken = first;
+          return true;
+        } else if (identical(currentType, TokenType.GT_GT_EQ)) {
+          int offset7 = _currentToken.offset;
+          Token first = new Token(TokenType.GT, offset7);
+          Token second = new Token(TokenType.GT, offset7 + 1);
+          Token third = new Token(TokenType.EQ, offset7 + 2);
           third.setNext(_currentToken.next);
           second.setNext(third);
           first.setNext(second);
@@ -658,7 +658,7 @@
   bool matchesAny(Token token, List<TokenType> types) {
     TokenType actualType = token.type;
     for (TokenType type in types) {
-      if (actualType == type) {
+      if (identical(actualType, type)) {
         return true;
       }
     }
@@ -675,7 +675,7 @@
    * built-in identifiers (pseudo-keywords).
    * @return {@code true} if the given token is a valid identifier
    */
-  bool matchesIdentifier2(Token token) => matches4(token, TokenType.IDENTIFIER) || (matches4(token, TokenType.KEYWORD) && (token as KeywordToken).keyword.isPseudoKeyword());
+  bool matchesIdentifier2(Token token) => matches4(token, TokenType.IDENTIFIER) || (matches4(token, TokenType.KEYWORD) && ((token as KeywordToken)).keyword.isPseudoKeyword());
   /**
    * If the current token has the given type, then advance to the next token and return {@code true}. Otherwise, return {@code false} without advancing.
    * @param type the type of token that can optionally appear in the current location
@@ -700,13 +700,13 @@
   Expression parseAdditiveExpression() {
     Expression expression;
     if (matches(Keyword.SUPER) && _currentToken.next.type.isAdditiveOperator()) {
-      expression = new SuperExpression(andAdvance);
+      expression = new SuperExpression.full(andAdvance);
     } else {
       expression = parseMultiplicativeExpression();
     }
     while (_currentToken.type.isAdditiveOperator()) {
       Token operator = andAdvance;
-      expression = new BinaryExpression(expression, operator, parseMultiplicativeExpression());
+      expression = new BinaryExpression.full(expression, operator, parseMultiplicativeExpression());
     }
     return expression;
   }
@@ -731,7 +731,7 @@
     if (matches5(TokenType.OPEN_PAREN)) {
       arguments = parseArgumentList();
     }
-    return new Annotation(atSign, name, period, constructorName, arguments);
+    return new Annotation.full(atSign, name, period, constructorName, arguments);
   }
   /**
    * Parse an argument.
@@ -746,9 +746,9 @@
    */
   Expression parseArgument() {
     if (matchesIdentifier() && matches4(peek(), TokenType.COLON)) {
-      SimpleIdentifier label = new SimpleIdentifier(andAdvance);
-      Label name = new Label(label, andAdvance);
-      return new NamedExpression(name, parseExpression2());
+      SimpleIdentifier label = new SimpleIdentifier.full(andAdvance);
+      Label name = new Label.full(label, andAdvance);
+      return new NamedExpression.full(name, parseExpression2());
     } else {
       return parseExpression2();
     }
@@ -764,7 +764,7 @@
   ArgumentDefinitionTest parseArgumentDefinitionTest() {
     Token question = expect2(TokenType.QUESTION);
     SimpleIdentifier identifier = parseSimpleIdentifier();
-    return new ArgumentDefinitionTest(question, identifier);
+    return new ArgumentDefinitionTest.full(question, identifier);
   }
   /**
    * Parse a list of arguments.
@@ -781,7 +781,7 @@
     Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
     List<Expression> arguments = new List<Expression>();
     if (matches5(TokenType.CLOSE_PAREN)) {
-      return new ArgumentList(leftParenthesis, arguments, andAdvance);
+      return new ArgumentList.full(leftParenthesis, arguments, andAdvance);
     }
     Expression argument = parseArgument();
     arguments.add(argument);
@@ -800,7 +800,7 @@
       }
     }
     Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
-    return new ArgumentList(leftParenthesis, arguments, rightParenthesis);
+    return new ArgumentList.full(leftParenthesis, arguments, rightParenthesis);
   }
   /**
    * Parse an assert statement.
@@ -816,7 +816,7 @@
     Expression expression = parseConditionalExpression();
     Token rightParen = expect2(TokenType.CLOSE_PAREN);
     Token semicolon = expect2(TokenType.SEMICOLON);
-    return new AssertStatement(keyword, leftParen, expression, rightParen, semicolon);
+    return new AssertStatement.full(keyword, leftParen, expression, rightParen, semicolon);
   }
   /**
    * Parse an assignable expression.
@@ -832,7 +832,7 @@
    */
   Expression parseAssignableExpression(bool primaryAllowed) {
     if (matches(Keyword.SUPER)) {
-      return parseAssignableSelector(new SuperExpression(andAdvance), false);
+      return parseAssignableSelector(new SuperExpression.full(andAdvance), false);
     }
     Expression expression = parsePrimaryExpression();
     bool isOptional = primaryAllowed || expression is SimpleIdentifier;
@@ -840,25 +840,25 @@
       while (matches5(TokenType.OPEN_PAREN)) {
         ArgumentList argumentList = parseArgumentList();
         if (expression is SimpleIdentifier) {
-          expression = new MethodInvocation(null, null, expression as SimpleIdentifier, argumentList);
+          expression = new MethodInvocation.full(null, null, (expression as SimpleIdentifier), argumentList);
         } else if (expression is PrefixedIdentifier) {
-          PrefixedIdentifier identifier = expression as PrefixedIdentifier;
-          expression = new MethodInvocation(identifier.prefix, identifier.period, identifier.identifier, argumentList);
+          PrefixedIdentifier identifier = (expression as PrefixedIdentifier);
+          expression = new MethodInvocation.full(identifier.prefix, identifier.period, identifier.identifier, argumentList);
         } else if (expression is PropertyAccess) {
-          PropertyAccess access = expression as PropertyAccess;
-          expression = new MethodInvocation(access.target, access.operator, access.propertyName, argumentList);
+          PropertyAccess access = (expression as PropertyAccess);
+          expression = new MethodInvocation.full(access.target, access.operator, access.propertyName, argumentList);
         } else {
-          expression = new FunctionExpressionInvocation(expression, argumentList);
+          expression = new FunctionExpressionInvocation.full(expression, argumentList);
         }
         if (!primaryAllowed) {
           isOptional = false;
         }
       }
       Expression selectorExpression = parseAssignableSelector(expression, isOptional || (expression is PrefixedIdentifier));
-      if (selectorExpression == expression) {
+      if (identical(selectorExpression, expression)) {
         if (!isOptional && (expression is PrefixedIdentifier)) {
-          PrefixedIdentifier identifier = expression as PrefixedIdentifier;
-          expression = new PropertyAccess(identifier.prefix, identifier.period, identifier.identifier);
+          PrefixedIdentifier identifier = (expression as PrefixedIdentifier);
+          expression = new PropertyAccess.full(identifier.prefix, identifier.period, identifier.identifier);
         }
         return expression;
       }
@@ -882,10 +882,10 @@
       Token leftBracket = andAdvance;
       Expression index = parseExpression2();
       Token rightBracket = expect2(TokenType.CLOSE_SQUARE_BRACKET);
-      return new IndexExpression.con1(prefix, leftBracket, index, rightBracket);
+      return new IndexExpression.forTarget_full(prefix, leftBracket, index, rightBracket);
     } else if (matches5(TokenType.PERIOD)) {
       Token period = andAdvance;
-      return new PropertyAccess(prefix, period, parseSimpleIdentifier());
+      return new PropertyAccess.full(prefix, period, parseSimpleIdentifier());
     } else {
       if (!optional) {
         reportError3(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []);
@@ -905,13 +905,13 @@
   Expression parseBitwiseAndExpression() {
     Expression expression;
     if (matches(Keyword.SUPER) && matches4(peek(), TokenType.AMPERSAND)) {
-      expression = new SuperExpression(andAdvance);
+      expression = new SuperExpression.full(andAdvance);
     } else {
       expression = parseEqualityExpression();
     }
     while (matches5(TokenType.AMPERSAND)) {
       Token operator = andAdvance;
-      expression = new BinaryExpression(expression, operator, parseEqualityExpression());
+      expression = new BinaryExpression.full(expression, operator, parseEqualityExpression());
     }
     return expression;
   }
@@ -927,13 +927,13 @@
   Expression parseBitwiseOrExpression() {
     Expression expression;
     if (matches(Keyword.SUPER) && matches4(peek(), TokenType.BAR)) {
-      expression = new SuperExpression(andAdvance);
+      expression = new SuperExpression.full(andAdvance);
     } else {
       expression = parseBitwiseXorExpression();
     }
     while (matches5(TokenType.BAR)) {
       Token operator = andAdvance;
-      expression = new BinaryExpression(expression, operator, parseBitwiseXorExpression());
+      expression = new BinaryExpression.full(expression, operator, parseBitwiseXorExpression());
     }
     return expression;
   }
@@ -949,13 +949,13 @@
   Expression parseBitwiseXorExpression() {
     Expression expression;
     if (matches(Keyword.SUPER) && matches4(peek(), TokenType.CARET)) {
-      expression = new SuperExpression(andAdvance);
+      expression = new SuperExpression.full(andAdvance);
     } else {
       expression = parseBitwiseAndExpression();
     }
     while (matches5(TokenType.CARET)) {
       Token operator = andAdvance;
-      expression = new BinaryExpression(expression, operator, parseBitwiseAndExpression());
+      expression = new BinaryExpression.full(expression, operator, parseBitwiseAndExpression());
     }
     return expression;
   }
@@ -976,14 +976,14 @@
       if (statement != null) {
         statements.add(statement);
       }
-      if (_currentToken == statementStart) {
+      if (identical(_currentToken, statementStart)) {
         reportError4(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
         advance();
       }
       statementStart = _currentToken;
     }
     Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET);
-    return new Block(leftBracket, statements, rightBracket);
+    return new Block.full(leftBracket, statements, rightBracket);
   }
   /**
    * Parse a break statement.
@@ -1003,7 +1003,7 @@
       reportError4(ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, breakKeyword, []);
     }
     Token semicolon = expect2(TokenType.SEMICOLON);
-    return new BreakStatement(breakKeyword, label, semicolon);
+    return new BreakStatement.full(breakKeyword, label, semicolon);
   }
   /**
    * Parse a cascade section.
@@ -1024,30 +1024,30 @@
     SimpleIdentifier functionName = null;
     if (matchesIdentifier()) {
       functionName = parseSimpleIdentifier();
-    } else if (_currentToken.type == TokenType.OPEN_SQUARE_BRACKET) {
+    } else if (identical(_currentToken.type, TokenType.OPEN_SQUARE_BRACKET)) {
       Token leftBracket = andAdvance;
       Expression index = parseExpression2();
       Token rightBracket = expect2(TokenType.CLOSE_SQUARE_BRACKET);
-      expression = new IndexExpression.con2(period, leftBracket, index, rightBracket);
+      expression = new IndexExpression.forCascade_full(period, leftBracket, index, rightBracket);
       period = null;
     } else {
       reportError4(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
       return expression;
     }
-    if (_currentToken.type == TokenType.OPEN_PAREN) {
-      while (_currentToken.type == TokenType.OPEN_PAREN) {
+    if (identical(_currentToken.type, TokenType.OPEN_PAREN)) {
+      while (identical(_currentToken.type, TokenType.OPEN_PAREN)) {
         if (functionName != null) {
-          expression = new MethodInvocation(expression, period, functionName, parseArgumentList());
+          expression = new MethodInvocation.full(expression, period, functionName, parseArgumentList());
           period = null;
           functionName = null;
         } else if (expression == null) {
           return null;
         } else {
-          expression = new FunctionExpressionInvocation(expression, parseArgumentList());
+          expression = new FunctionExpressionInvocation.full(expression, parseArgumentList());
         }
       }
     } else if (functionName != null) {
-      expression = new PropertyAccess(expression, period, functionName);
+      expression = new PropertyAccess.full(expression, period, functionName);
       period = null;
     }
     bool progress = true;
@@ -1057,15 +1057,15 @@
       if (selector != expression) {
         expression = selector;
         progress = true;
-        while (_currentToken.type == TokenType.OPEN_PAREN) {
-          expression = new FunctionExpressionInvocation(expression, parseArgumentList());
+        while (identical(_currentToken.type, TokenType.OPEN_PAREN)) {
+          expression = new FunctionExpressionInvocation.full(expression, parseArgumentList());
         }
       }
     }
     if (_currentToken.type.isAssignmentOperator()) {
       Token operator = andAdvance;
       ensureAssignable(expression);
-      expression = new AssignmentExpression(expression, operator, parseExpression2());
+      expression = new AssignmentExpression.full(expression, operator, parseExpression2());
     }
     return expression;
   }
@@ -1141,7 +1141,7 @@
       rightBracket = createSyntheticToken(TokenType.CLOSE_CURLY_BRACKET);
       reportError3(ParserErrorCode.MISSING_CLASS_BODY, []);
     }
-    return new ClassDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, abstractKeyword, keyword, name, typeParameters, extendsClause, withClause, implementsClause, leftBracket, members, rightBracket);
+    return new ClassDeclaration.full(commentAndMetadata.comment, commentAndMetadata.metadata, abstractKeyword, keyword, name, typeParameters, extendsClause, withClause, implementsClause, leftBracket, members, rightBracket);
   }
   /**
    * Parse a class member.
@@ -1242,7 +1242,7 @@
           members.add(member);
         }
       }
-      if (_currentToken == memberStart) {
+      if (identical(_currentToken, memberStart)) {
         reportError4(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
         advance();
       }
@@ -1280,7 +1280,7 @@
       implementsClause = parseImplementsClause();
     }
     Token semicolon = expect2(TokenType.SEMICOLON);
-    return new ClassTypeAlias(commentAndMetadata.comment, commentAndMetadata.metadata, keyword, name, typeParameters, equals, abstractKeyword, superclass, withClause, implementsClause, semicolon);
+    return new ClassTypeAlias.full(commentAndMetadata.comment, commentAndMetadata.metadata, keyword, name, typeParameters, equals, abstractKeyword, superclass, withClause, implementsClause, semicolon);
   }
   /**
    * Parse a list of combinators in a directive.
@@ -1293,14 +1293,14 @@
    */
   List<Combinator> parseCombinators() {
     List<Combinator> combinators = new List<Combinator>();
-    while (matches2(Parser._SHOW) || matches2(Parser._HIDE)) {
+    while (matches2(_SHOW) || matches2(_HIDE)) {
       Token keyword = expect2(TokenType.IDENTIFIER);
-      if (keyword.lexeme == Parser._SHOW) {
+      if (keyword.lexeme == _SHOW) {
         List<SimpleIdentifier> shownNames = parseIdentifierList();
-        combinators.add(new ShowCombinator(keyword, shownNames));
+        combinators.add(new ShowCombinator.full(keyword, shownNames));
       } else {
         List<SimpleIdentifier> hiddenNames = parseIdentifierList();
-        combinators.add(new HideCombinator(keyword, hiddenNames));
+        combinators.add(new HideCombinator.full(keyword, hiddenNames));
       }
     }
     return combinators;
@@ -1344,7 +1344,7 @@
     }
     try {
       List<bool> errorFound = [false];
-      AnalysisErrorListener listener = new AnalysisErrorListener_1(errorFound);
+      AnalysisErrorListener listener = new AnalysisErrorListener_4(errorFound);
       StringScanner scanner = new StringScanner(null, referenceSource, listener);
       scanner.setSourceStart(1, 1, sourceOffset);
       Token firstToken = scanner.tokenize();
@@ -1360,22 +1360,22 @@
           Token nextToken;
           Identifier identifier;
           if (matches4(secondToken, TokenType.PERIOD) && matchesIdentifier2(thirdToken)) {
-            identifier = new PrefixedIdentifier(new SimpleIdentifier(firstToken), secondToken, new SimpleIdentifier(thirdToken));
+            identifier = new PrefixedIdentifier.full(new SimpleIdentifier.full(firstToken), secondToken, new SimpleIdentifier.full(thirdToken));
             nextToken = thirdToken.next;
           } else {
-            identifier = new SimpleIdentifier(firstToken);
+            identifier = new SimpleIdentifier.full(firstToken);
             nextToken = firstToken.next;
           }
           if (nextToken.type != TokenType.EOF) {
           }
-          return new CommentReference(newKeyword, identifier);
+          return new CommentReference.full(newKeyword, identifier);
         } else if (matches3(firstToken, Keyword.THIS) || matches3(firstToken, Keyword.NULL) || matches3(firstToken, Keyword.TRUE) || matches3(firstToken, Keyword.FALSE)) {
           return null;
         } else if (matches4(firstToken, TokenType.STRING)) {
         } else {
         }
       }
-    } on Exception catch (exception) {
+    } on JavaException catch (exception) {
     }
     return null;
   }
@@ -1398,8 +1398,8 @@
       while (leftIndex >= 0) {
         int rightIndex = comment.indexOf(']', leftIndex);
         if (rightIndex >= 0) {
-          int firstChar = comment.charCodeAt(leftIndex + 1);
-          if (firstChar != 0x27 && firstChar != 0x22 && firstChar != 0x3a) {
+          int firstChar = comment.codeUnitAt(leftIndex + 1);
+          if (firstChar != 0x27 && firstChar != 0x22 && firstChar != 0x3A) {
             CommentReference reference = parseCommentReference(comment.substring(leftIndex + 1, rightIndex), token.offset + leftIndex + 1);
             if (reference != null) {
               references.add(reference);
@@ -1438,7 +1438,7 @@
     }
     ScriptTag scriptTag = null;
     if (matches5(TokenType.SCRIPT_TAG)) {
-      scriptTag = new ScriptTag(andAdvance);
+      scriptTag = new ScriptTag.full(andAdvance);
     }
     bool libraryDirectiveFound = false;
     bool partOfDirectiveFound = false;
@@ -1497,13 +1497,13 @@
           declarations.add(member);
         }
       }
-      if (_currentToken == memberStart) {
+      if (identical(_currentToken, memberStart)) {
         reportError4(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
         advance();
       }
       memberStart = _currentToken;
     }
-    return new CompilationUnit(firstToken, scriptTag, directives, declarations, _currentToken);
+    return new CompilationUnit.full(firstToken, scriptTag, directives, declarations, _currentToken);
   }
   /**
    * Parse a compilation unit member.
@@ -1544,7 +1544,7 @@
         if (matchesIdentifier()) {
           if (matchesAny(peek(), [TokenType.EQ, TokenType.COMMA, TokenType.SEMICOLON])) {
             reportError(ParserErrorCode.VOID_VARIABLE, returnType, []);
-            return new TopLevelVariableDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, parseVariableDeclarationList2(validateModifiersForTopLevelVariable(modifiers), null), expect2(TokenType.SEMICOLON));
+            return new TopLevelVariableDeclaration.full(commentAndMetadata.comment, commentAndMetadata.metadata, parseVariableDeclarationList2(validateModifiersForTopLevelVariable(modifiers), null), expect2(TokenType.SEMICOLON));
           }
         }
         return null;
@@ -1560,7 +1560,7 @@
       validateModifiersForTopLevelFunction(modifiers);
       return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, null, false);
     } else if (matchesAny(peek(), [TokenType.EQ, TokenType.COMMA, TokenType.SEMICOLON])) {
-      return new TopLevelVariableDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, parseVariableDeclarationList2(validateModifiersForTopLevelVariable(modifiers), null), expect2(TokenType.SEMICOLON));
+      return new TopLevelVariableDeclaration.full(commentAndMetadata.comment, commentAndMetadata.metadata, parseVariableDeclarationList2(validateModifiersForTopLevelVariable(modifiers), null), expect2(TokenType.SEMICOLON));
     }
     TypeName returnType = parseReturnType();
     if (matches(Keyword.GET) || matches(Keyword.SET)) {
@@ -1573,7 +1573,7 @@
       validateModifiersForTopLevelFunction(modifiers);
       return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, returnType, false);
     }
-    return new TopLevelVariableDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, parseVariableDeclarationList2(validateModifiersForTopLevelVariable(modifiers), returnType), expect2(TokenType.SEMICOLON));
+    return new TopLevelVariableDeclaration.full(commentAndMetadata.comment, commentAndMetadata.metadata, parseVariableDeclarationList2(validateModifiersForTopLevelVariable(modifiers), returnType), expect2(TokenType.SEMICOLON));
   }
   /**
    * Parse a conditional expression.
@@ -1592,7 +1592,7 @@
     Expression thenExpression = parseExpressionWithoutCascade();
     Token colon = expect2(TokenType.COLON);
     Expression elseExpression = parseExpressionWithoutCascade();
-    return new ConditionalExpression(condition, question, thenExpression, colon, elseExpression);
+    return new ConditionalExpression.full(condition, question, thenExpression, colon, elseExpression);
   }
   /**
    * Parse a const expression.
@@ -1645,14 +1645,14 @@
     if (matches5(TokenType.EQ)) {
       separator = andAdvance;
       redirectedConstructor = parseConstructorName();
-      body = new EmptyFunctionBody(expect2(TokenType.SEMICOLON));
+      body = new EmptyFunctionBody.full(expect2(TokenType.SEMICOLON));
     } else {
       body = parseFunctionBody(true, false);
       if (!bodyAllowed && body is! EmptyFunctionBody) {
         reportError3(ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY, []);
       }
     }
-    return new ConstructorDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, constKeyword, factoryKeyword, returnType, period, name, parameters, separator, initializers, redirectedConstructor, body);
+    return new ConstructorDeclaration.full(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, constKeyword, factoryKeyword, returnType, period, name, parameters, separator, initializers, redirectedConstructor, body);
   }
   /**
    * Parse a field initializer within a constructor.
@@ -1673,18 +1673,18 @@
     Token equals = expect2(TokenType.EQ);
     Expression expression = parseConditionalExpression();
     TokenType tokenType = _currentToken.type;
-    if (tokenType == TokenType.PERIOD_PERIOD) {
+    if (identical(tokenType, TokenType.PERIOD_PERIOD)) {
       List<Expression> cascadeSections = new List<Expression>();
-      while (tokenType == TokenType.PERIOD_PERIOD) {
+      while (identical(tokenType, TokenType.PERIOD_PERIOD)) {
         Expression section = parseCascadeSection();
         if (section != null) {
           cascadeSections.add(section);
         }
         tokenType = _currentToken.type;
       }
-      expression = new CascadeExpression(expression, cascadeSections);
+      expression = new CascadeExpression.full(expression, cascadeSections);
     }
-    return new ConstructorFieldInitializer(keyword, period, fieldName, equals, expression);
+    return new ConstructorFieldInitializer.full(keyword, period, fieldName, equals, expression);
   }
   /**
    * Parse the name of a constructor.
@@ -1702,7 +1702,7 @@
       period = andAdvance;
       name = parseSimpleIdentifier();
     }
-    return new ConstructorName(type, period, name);
+    return new ConstructorName.full(type, period, name);
   }
   /**
    * Parse a continue statement.
@@ -1725,7 +1725,7 @@
       reportError4(ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE, continueKeyword, []);
     }
     Token semicolon = expect2(TokenType.SEMICOLON);
-    return new ContinueStatement(continueKeyword, label, semicolon);
+    return new ContinueStatement.full(continueKeyword, label, semicolon);
   }
   /**
    * Parse a directive.
@@ -1765,7 +1765,7 @@
     List<Token> commentTokens = new List<Token>();
     Token commentToken = _currentToken.precedingComments;
     while (commentToken != null) {
-      if (commentToken.type == TokenType.SINGLE_LINE_COMMENT) {
+      if (identical(commentToken.type, TokenType.SINGLE_LINE_COMMENT)) {
         if (commentToken.lexeme.startsWith("///")) {
           if (commentTokens.length == 1 && commentTokens[0].lexeme.startsWith("/**")) {
             commentTokens.clear();
@@ -1806,7 +1806,7 @@
       Expression condition = parseExpression2();
       Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
       Token semicolon = expect2(TokenType.SEMICOLON);
-      return new DoStatement(doKeyword, body, whileKeyword, leftParenthesis, condition, rightParenthesis, semicolon);
+      return new DoStatement.full(doKeyword, body, whileKeyword, leftParenthesis, condition, rightParenthesis, semicolon);
     } finally {
       _inLoop = wasInLoop;
     }
@@ -1819,7 +1819,7 @@
    * </pre>
    * @return the empty statement that was parsed
    */
-  Statement parseEmptyStatement() => new EmptyStatement(andAdvance);
+  Statement parseEmptyStatement() => new EmptyStatement.full(andAdvance);
   /**
    * Parse an equality expression.
    * <pre>
@@ -1832,13 +1832,13 @@
   Expression parseEqualityExpression() {
     Expression expression;
     if (matches(Keyword.SUPER) && _currentToken.next.type.isEqualityOperator()) {
-      expression = new SuperExpression(andAdvance);
+      expression = new SuperExpression.full(andAdvance);
     } else {
       expression = parseRelationalExpression();
     }
     while (_currentToken.type.isEqualityOperator()) {
       Token operator = andAdvance;
-      expression = new BinaryExpression(expression, operator, parseRelationalExpression());
+      expression = new BinaryExpression.full(expression, operator, parseRelationalExpression());
     }
     return expression;
   }
@@ -1856,7 +1856,7 @@
     StringLiteral libraryUri = parseStringLiteral();
     List<Combinator> combinators = parseCombinators();
     Token semicolon = expect2(TokenType.SEMICOLON);
-    return new ExportDirective(commentAndMetadata.comment, commentAndMetadata.metadata, exportKeyword, libraryUri, combinators, semicolon);
+    return new ExportDirective.full(commentAndMetadata.comment, commentAndMetadata.metadata, exportKeyword, libraryUri, combinators, semicolon);
   }
   /**
    * Parse an expression that does not contain any cascades.
@@ -1874,20 +1874,20 @@
     }
     Expression expression = parseConditionalExpression();
     TokenType tokenType = _currentToken.type;
-    if (tokenType == TokenType.PERIOD_PERIOD) {
+    if (identical(tokenType, TokenType.PERIOD_PERIOD)) {
       List<Expression> cascadeSections = new List<Expression>();
-      while (tokenType == TokenType.PERIOD_PERIOD) {
+      while (identical(tokenType, TokenType.PERIOD_PERIOD)) {
         Expression section = parseCascadeSection();
         if (section != null) {
           cascadeSections.add(section);
         }
         tokenType = _currentToken.type;
       }
-      return new CascadeExpression(expression, cascadeSections);
+      return new CascadeExpression.full(expression, cascadeSections);
     } else if (tokenType.isAssignmentOperator()) {
       Token operator = andAdvance;
       ensureAssignable(expression);
-      return new AssignmentExpression(expression, operator, parseExpression2());
+      return new AssignmentExpression.full(expression, operator, parseExpression2());
     }
     return expression;
   }
@@ -1925,7 +1925,7 @@
     if (_currentToken.type.isAssignmentOperator()) {
       Token operator = andAdvance;
       ensureAssignable(expression);
-      expression = new AssignmentExpression(expression, operator, parseExpressionWithoutCascade());
+      expression = new AssignmentExpression.full(expression, operator, parseExpressionWithoutCascade());
     }
     return expression;
   }
@@ -1940,7 +1940,7 @@
   ExtendsClause parseExtendsClause() {
     Token keyword = expect(Keyword.EXTENDS);
     TypeName superclass = parseTypeName();
-    return new ExtendsClause(keyword, superclass);
+    return new ExtendsClause.full(keyword, superclass);
   }
   /**
    * Parse the 'final', 'const', 'var' or type preceding a variable declaration.
@@ -1990,23 +1990,23 @@
     if (matches5(TokenType.EQ)) {
       Token seperator = andAdvance;
       Expression defaultValue = parseExpression2();
-      if (kind == ParameterKind.NAMED) {
+      if (identical(kind, ParameterKind.NAMED)) {
         reportError4(ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER, seperator, []);
-      } else if (kind == ParameterKind.REQUIRED) {
+      } else if (identical(kind, ParameterKind.REQUIRED)) {
         reportError(ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP, parameter, []);
       }
-      return new DefaultFormalParameter(parameter, kind, seperator, defaultValue);
+      return new DefaultFormalParameter.full(parameter, kind, seperator, defaultValue);
     } else if (matches5(TokenType.COLON)) {
       Token seperator = andAdvance;
       Expression defaultValue = parseExpression2();
-      if (kind == ParameterKind.POSITIONAL) {
+      if (identical(kind, ParameterKind.POSITIONAL)) {
         reportError4(ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER, seperator, []);
-      } else if (kind == ParameterKind.REQUIRED) {
+      } else if (identical(kind, ParameterKind.REQUIRED)) {
         reportError(ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP, parameter, []);
       }
-      return new DefaultFormalParameter(parameter, kind, seperator, defaultValue);
+      return new DefaultFormalParameter.full(parameter, kind, seperator, defaultValue);
     } else if (kind != ParameterKind.REQUIRED) {
-      return new DefaultFormalParameter(parameter, kind, null, null);
+      return new DefaultFormalParameter.full(parameter, kind, null, null);
     }
     return parameter;
   }
@@ -2032,7 +2032,7 @@
   FormalParameterList parseFormalParameterList() {
     Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
     if (matches5(TokenType.CLOSE_PAREN)) {
-      return new FormalParameterList(leftParenthesis, null, null, null, andAdvance);
+      return new FormalParameterList.full(leftParenthesis, null, null, null, andAdvance);
     }
     List<FormalParameter> parameters = new List<FormalParameter>();
     List<FormalParameter> normalParameters = new List<FormalParameter>();
@@ -2053,7 +2053,7 @@
       if (firstParameter) {
         firstParameter = false;
       } else if (!optional(TokenType.COMMA)) {
-        if ((leftParenthesis as BeginToken).endToken != null) {
+        if (((leftParenthesis as BeginToken)).endToken != null) {
           reportError3(ParserErrorCode.EXPECTED_TOKEN, [TokenType.COMMA.lexeme]);
         } else {
           break;
@@ -2113,7 +2113,7 @@
     if (rightSquareBracket == null) {
       rightSquareBracket = rightCurlyBracket;
     }
-    return new FormalParameterList(leftParenthesis, parameters, leftSquareBracket, rightSquareBracket, rightParenthesis);
+    return new FormalParameterList.full(leftParenthesis, parameters, leftSquareBracket, rightSquareBracket, rightParenthesis);
   }
   /**
    * Parse a for statement.
@@ -2142,8 +2142,8 @@
         if (matchesIdentifier() && matches3(peek(), Keyword.IN)) {
           List<VariableDeclaration> variables = new List<VariableDeclaration>();
           SimpleIdentifier variableName = parseSimpleIdentifier();
-          variables.add(new VariableDeclaration(null, null, variableName, null, null));
-          variableList = new VariableDeclarationList(null, null, variables);
+          variables.add(new VariableDeclaration.full(null, null, variableName, null, null));
+          variableList = new VariableDeclarationList.full(null, null, variables);
         } else if (isInitializedVariableDeclaration()) {
           variableList = parseVariableDeclarationList();
         } else {
@@ -2154,21 +2154,21 @@
           if (variableList == null) {
             reportError3(ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH, []);
           } else {
-            NodeList<VariableDeclaration> variables5 = variableList.variables;
-            if (variables5.length > 1) {
-              reportError3(ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH, [variables5.length.toString()]);
+            NodeList<VariableDeclaration> variables3 = variableList.variables;
+            if (variables3.length > 1) {
+              reportError3(ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH, [variables3.length.toString()]);
             }
-            VariableDeclaration variable = variables5[0];
+            VariableDeclaration variable = variables3[0];
             if (variable.initializer != null) {
               reportError3(ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH, []);
             }
-            loopParameter = new SimpleFormalParameter(null, null, variableList.keyword, variableList.type, variable.name);
+            loopParameter = new SimpleFormalParameter.full(null, null, variableList.keyword, variableList.type, variable.name);
           }
           Token inKeyword = expect(Keyword.IN);
           Expression iterator = parseExpression2();
           Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
           Statement body = parseStatement2();
-          return new ForEachStatement(forKeyword, leftParenthesis, loopParameter, inKeyword, iterator, rightParenthesis, body);
+          return new ForEachStatement.full(forKeyword, leftParenthesis, loopParameter, inKeyword, iterator, rightParenthesis, body);
         }
       }
       Token leftSeparator = expect2(TokenType.SEMICOLON);
@@ -2183,7 +2183,7 @@
       }
       Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
       Statement body = parseStatement2();
-      return new ForStatement(forKeyword, leftParenthesis, variableList, initialization, leftSeparator, condition, rightSeparator, updaters, rightParenthesis, body);
+      return new ForStatement.full(forKeyword, leftParenthesis, variableList, initialization, leftSeparator, condition, rightSeparator, updaters, rightParenthesis, body);
     } finally {
       _inLoop = wasInLoop;
     }
@@ -2213,7 +2213,7 @@
         if (!mayBeEmpty) {
           reportError3(ParserErrorCode.MISSING_FUNCTION_BODY, []);
         }
-        return new EmptyFunctionBody(andAdvance);
+        return new EmptyFunctionBody.full(andAdvance);
       } else if (matches5(TokenType.FUNCTION)) {
         Token functionDefinition = andAdvance;
         Expression expression = parseExpression2();
@@ -2221,16 +2221,16 @@
         if (!inExpression) {
           semicolon = expect2(TokenType.SEMICOLON);
         }
-        return new ExpressionFunctionBody(functionDefinition, expression, semicolon);
+        return new ExpressionFunctionBody.full(functionDefinition, expression, semicolon);
       } else if (matches5(TokenType.OPEN_CURLY_BRACKET)) {
-        return new BlockFunctionBody(parseBlock());
+        return new BlockFunctionBody.full(parseBlock());
       } else if (matches2("native")) {
         advance();
         parseStringLiteral();
-        return new EmptyFunctionBody(andAdvance);
+        return new EmptyFunctionBody.full(andAdvance);
       } else {
         reportError3(ParserErrorCode.MISSING_FUNCTION_BODY, []);
-        return new EmptyFunctionBody(createSyntheticToken(TokenType.SEMICOLON));
+        return new EmptyFunctionBody.full(createSyntheticToken(TokenType.SEMICOLON));
       }
     } finally {
       _inLoop = wasInLoop;
@@ -2281,7 +2281,7 @@
       reportError3(ParserErrorCode.UNEXPECTED_TOKEN, [_currentToken.lexeme]);
       advance();
     }
-    return new FunctionDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, returnType, keyword, name, new FunctionExpression(parameters, body));
+    return new FunctionDeclaration.full(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, returnType, keyword, name, new FunctionExpression.full(parameters, body));
   }
   /**
    * Parse a function declaration statement.
@@ -2303,7 +2303,7 @@
    * @param returnType the return type, or {@code null} if there is no return type
    * @return the function declaration statement that was parsed
    */
-  Statement parseFunctionDeclarationStatement2(CommentAndMetadata commentAndMetadata, TypeName returnType) => new FunctionDeclarationStatement(parseFunctionDeclaration(commentAndMetadata, null, returnType, true));
+  Statement parseFunctionDeclarationStatement2(CommentAndMetadata commentAndMetadata, TypeName returnType) => new FunctionDeclarationStatement.full(parseFunctionDeclaration(commentAndMetadata, null, returnType, true));
   /**
    * Parse a function expression.
    * <pre>
@@ -2316,7 +2316,7 @@
     FormalParameterList parameters = parseFormalParameterList();
     validateFormalParameterList(parameters);
     FunctionBody body = parseFunctionBody(false, true);
-    return new FunctionExpression(parameters, body);
+    return new FunctionExpression.full(parameters, body);
   }
   /**
    * Parse a function type alias.
@@ -2342,16 +2342,16 @@
     }
     if (matches5(TokenType.SEMICOLON)) {
       reportError3(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, []);
-      FormalParameterList parameters = new FormalParameterList(createSyntheticToken(TokenType.OPEN_PAREN), null, null, null, createSyntheticToken(TokenType.CLOSE_PAREN));
+      FormalParameterList parameters = new FormalParameterList.full(createSyntheticToken(TokenType.OPEN_PAREN), null, null, null, createSyntheticToken(TokenType.CLOSE_PAREN));
       Token semicolon = expect2(TokenType.SEMICOLON);
-      return new FunctionTypeAlias(commentAndMetadata.comment, commentAndMetadata.metadata, keyword, returnType, name, typeParameters, parameters, semicolon);
+      return new FunctionTypeAlias.full(commentAndMetadata.comment, commentAndMetadata.metadata, keyword, returnType, name, typeParameters, parameters, semicolon);
     } else if (!matches5(TokenType.OPEN_PAREN)) {
       return null;
     }
     FormalParameterList parameters = parseFormalParameterList();
     validateFormalParameterList(parameters);
     Token semicolon = expect2(TokenType.SEMICOLON);
-    return new FunctionTypeAlias(commentAndMetadata.comment, commentAndMetadata.metadata, keyword, returnType, name, typeParameters, parameters, semicolon);
+    return new FunctionTypeAlias.full(commentAndMetadata.comment, commentAndMetadata.metadata, keyword, returnType, name, typeParameters, parameters, semicolon);
   }
   /**
    * Parse a getter.
@@ -2381,7 +2381,7 @@
     if (externalKeyword != null && body is! EmptyFunctionBody) {
       reportError3(ParserErrorCode.EXTERNAL_GETTER_WITH_BODY, []);
     }
-    return new MethodDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, staticKeyword, returnType, propertyKeyword, null, name, null, body);
+    return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, staticKeyword, returnType, propertyKeyword, null, name, null, body);
   }
   /**
    * Parse a list of identifiers.
@@ -2420,7 +2420,7 @@
       elseKeyword = andAdvance;
       elseStatement = parseStatement2();
     }
-    return new IfStatement(ifKeyword, leftParenthesis, condition, rightParenthesis, thenStatement, elseKeyword, elseStatement);
+    return new IfStatement.full(ifKeyword, leftParenthesis, condition, rightParenthesis, thenStatement, elseKeyword, elseStatement);
   }
   /**
    * Parse an implements clause.
@@ -2437,7 +2437,7 @@
     while (optional(TokenType.COMMA)) {
       interfaces.add(parseTypeName());
     }
-    return new ImplementsClause(keyword, interfaces);
+    return new ImplementsClause.full(keyword, interfaces);
   }
   /**
    * Parse an import directive.
@@ -2459,7 +2459,7 @@
     }
     List<Combinator> combinators = parseCombinators();
     Token semicolon = expect2(TokenType.SEMICOLON);
-    return new ImportDirective(commentAndMetadata.comment, commentAndMetadata.metadata, importKeyword, libraryUri, asToken, prefix, combinators, semicolon);
+    return new ImportDirective.full(commentAndMetadata.comment, commentAndMetadata.metadata, importKeyword, libraryUri, asToken, prefix, combinators, semicolon);
   }
   /**
    * Parse a list of initialized identifiers.
@@ -2482,7 +2482,7 @@
    */
   FieldDeclaration parseInitializedIdentifierList(CommentAndMetadata commentAndMetadata, Token staticKeyword, Token keyword, TypeName type) {
     VariableDeclarationList fieldList = parseVariableDeclarationList2(keyword, type);
-    return new FieldDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, staticKeyword, fieldList, expect2(TokenType.SEMICOLON));
+    return new FieldDeclaration.full(commentAndMetadata.comment, commentAndMetadata.metadata, staticKeyword, fieldList, expect2(TokenType.SEMICOLON));
   }
   /**
    * Parse an instance creation expression.
@@ -2496,7 +2496,7 @@
   InstanceCreationExpression parseInstanceCreationExpression(Token keyword) {
     ConstructorName constructorName = parseConstructorName();
     ArgumentList argumentList = parseArgumentList();
-    return new InstanceCreationExpression(keyword, constructorName, argumentList);
+    return new InstanceCreationExpression.full(keyword, constructorName, argumentList);
   }
   /**
    * Parse a library directive.
@@ -2511,7 +2511,7 @@
     Token keyword = expect(Keyword.LIBRARY);
     LibraryIdentifier libraryName = parseLibraryName(ParserErrorCode.MISSING_NAME_IN_LIBRARY_DIRECTIVE, keyword);
     Token semicolon = expect2(TokenType.SEMICOLON);
-    return new LibraryDirective(commentAndMetadata.comment, commentAndMetadata.metadata, keyword, libraryName, semicolon);
+    return new LibraryDirective.full(commentAndMetadata.comment, commentAndMetadata.metadata, keyword, libraryName, semicolon);
   }
   /**
    * Parse a library identifier.
@@ -2528,7 +2528,7 @@
       advance();
       components.add(parseSimpleIdentifier());
     }
-    return new LibraryIdentifier(components);
+    return new LibraryIdentifier.full(components);
   }
   /**
    * Parse a library name.
@@ -2552,7 +2552,7 @@
     }
     List<SimpleIdentifier> components = new List<SimpleIdentifier>();
     components.add(createSyntheticIdentifier());
-    return new LibraryIdentifier(components);
+    return new LibraryIdentifier.full(components);
   }
   /**
    * Parse a list literal.
@@ -2570,27 +2570,27 @@
     if (matches5(TokenType.INDEX)) {
       BeginToken leftBracket = new BeginToken(TokenType.OPEN_SQUARE_BRACKET, _currentToken.offset);
       Token rightBracket = new Token(TokenType.CLOSE_SQUARE_BRACKET, _currentToken.offset + 1);
-      leftBracket.endToken2 = rightBracket;
+      leftBracket.endToken = rightBracket;
       rightBracket.setNext(_currentToken.next);
       leftBracket.setNext(rightBracket);
       _currentToken.previous.setNext(leftBracket);
       _currentToken = _currentToken.next;
-      return new ListLiteral(modifier, typeArguments, leftBracket, null, rightBracket);
+      return new ListLiteral.full(modifier, typeArguments, leftBracket, null, rightBracket);
     }
     Token leftBracket = expect2(TokenType.OPEN_SQUARE_BRACKET);
     if (matches5(TokenType.CLOSE_SQUARE_BRACKET)) {
-      return new ListLiteral(modifier, typeArguments, leftBracket, null, andAdvance);
+      return new ListLiteral.full(modifier, typeArguments, leftBracket, null, andAdvance);
     }
     List<Expression> elements = new List<Expression>();
     elements.add(parseExpression2());
     while (optional(TokenType.COMMA)) {
       if (matches5(TokenType.CLOSE_SQUARE_BRACKET)) {
-        return new ListLiteral(modifier, typeArguments, leftBracket, elements, andAdvance);
+        return new ListLiteral.full(modifier, typeArguments, leftBracket, elements, andAdvance);
       }
       elements.add(parseExpression2());
     }
     Token rightBracket = expect2(TokenType.CLOSE_SQUARE_BRACKET);
-    return new ListLiteral(modifier, typeArguments, leftBracket, elements, rightBracket);
+    return new ListLiteral.full(modifier, typeArguments, leftBracket, elements, rightBracket);
   }
   /**
    * Parse a list or map literal.
@@ -2614,7 +2614,7 @@
       return parseListLiteral(modifier, typeArguments);
     }
     reportError3(ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL, []);
-    return new ListLiteral(modifier, typeArguments, createSyntheticToken(TokenType.OPEN_SQUARE_BRACKET), null, createSyntheticToken(TokenType.CLOSE_SQUARE_BRACKET));
+    return new ListLiteral.full(modifier, typeArguments, createSyntheticToken(TokenType.OPEN_SQUARE_BRACKET), null, createSyntheticToken(TokenType.CLOSE_SQUARE_BRACKET));
   }
   /**
    * Parse a logical and expression.
@@ -2628,7 +2628,7 @@
     Expression expression = parseBitwiseOrExpression();
     while (matches5(TokenType.AMPERSAND_AMPERSAND)) {
       Token operator = andAdvance;
-      expression = new BinaryExpression(expression, operator, parseBitwiseOrExpression());
+      expression = new BinaryExpression.full(expression, operator, parseBitwiseOrExpression());
     }
     return expression;
   }
@@ -2644,7 +2644,7 @@
     Expression expression = parseLogicalAndExpression();
     while (matches5(TokenType.BAR_BAR)) {
       Token operator = andAdvance;
-      expression = new BinaryExpression(expression, operator, parseLogicalAndExpression());
+      expression = new BinaryExpression.full(expression, operator, parseLogicalAndExpression());
     }
     return expression;
   }
@@ -2664,17 +2664,17 @@
     Token leftBracket = expect2(TokenType.OPEN_CURLY_BRACKET);
     List<MapLiteralEntry> entries = new List<MapLiteralEntry>();
     if (matches5(TokenType.CLOSE_CURLY_BRACKET)) {
-      return new MapLiteral(modifier, typeArguments, leftBracket, entries, andAdvance);
+      return new MapLiteral.full(modifier, typeArguments, leftBracket, entries, andAdvance);
     }
     entries.add(parseMapLiteralEntry());
     while (optional(TokenType.COMMA)) {
       if (matches5(TokenType.CLOSE_CURLY_BRACKET)) {
-        return new MapLiteral(modifier, typeArguments, leftBracket, entries, andAdvance);
+        return new MapLiteral.full(modifier, typeArguments, leftBracket, entries, andAdvance);
       }
       entries.add(parseMapLiteralEntry());
     }
     Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET);
-    return new MapLiteral(modifier, typeArguments, leftBracket, entries, rightBracket);
+    return new MapLiteral.full(modifier, typeArguments, leftBracket, entries, rightBracket);
   }
   /**
    * Parse a map literal entry.
@@ -2688,7 +2688,7 @@
     StringLiteral key = parseStringLiteral();
     Token separator = expect2(TokenType.COLON);
     Expression value = parseExpression2();
-    return new MapLiteralEntry(key, separator, value);
+    return new MapLiteralEntry.full(key, separator, value);
   }
   /**
    * Parse a method declaration.
@@ -2737,7 +2737,7 @@
         reportError(ParserErrorCode.ABSTRACT_STATIC_METHOD, body, []);
       }
     }
-    return new MethodDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, staticKeyword, returnType, null, null, name, parameters, body);
+    return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, staticKeyword, returnType, null, null, name, parameters, body);
   }
   /**
    * Parse the modifiers preceding a declaration. This method allows the modifiers to appear in any
@@ -2759,49 +2759,49 @@
           reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
-          modifiers.abstractKeyword4 = andAdvance;
+          modifiers.abstractKeyword = andAdvance;
         }
       } else if (matches(Keyword.CONST)) {
         if (modifiers.constKeyword != null) {
           reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
-          modifiers.constKeyword3 = andAdvance;
+          modifiers.constKeyword = andAdvance;
         }
       } else if (matches(Keyword.EXTERNAL)) {
         if (modifiers.externalKeyword != null) {
           reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
-          modifiers.externalKeyword5 = andAdvance;
+          modifiers.externalKeyword = andAdvance;
         }
       } else if (matches(Keyword.FACTORY)) {
         if (modifiers.factoryKeyword != null) {
           reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
-          modifiers.factoryKeyword3 = andAdvance;
+          modifiers.factoryKeyword = andAdvance;
         }
       } else if (matches(Keyword.FINAL)) {
         if (modifiers.finalKeyword != null) {
           reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
-          modifiers.finalKeyword2 = andAdvance;
+          modifiers.finalKeyword = andAdvance;
         }
       } else if (matches(Keyword.STATIC)) {
         if (modifiers.staticKeyword != null) {
           reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
-          modifiers.staticKeyword2 = andAdvance;
+          modifiers.staticKeyword = andAdvance;
         }
       } else if (matches(Keyword.VAR)) {
         if (modifiers.varKeyword != null) {
           reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
           advance();
         } else {
-          modifiers.varKeyword2 = andAdvance;
+          modifiers.varKeyword = andAdvance;
         }
       } else {
         progress = false;
@@ -2821,13 +2821,13 @@
   Expression parseMultiplicativeExpression() {
     Expression expression;
     if (matches(Keyword.SUPER) && _currentToken.next.type.isMultiplicativeOperator()) {
-      expression = new SuperExpression(andAdvance);
+      expression = new SuperExpression.full(andAdvance);
     } else {
       expression = parseUnaryExpression();
     }
     while (_currentToken.type.isMultiplicativeOperator()) {
       Token operator = andAdvance;
-      expression = new BinaryExpression(expression, operator, parseUnaryExpression());
+      expression = new BinaryExpression.full(expression, operator, parseUnaryExpression());
     }
     return expression;
   }
@@ -2866,38 +2866,38 @@
     if (matches5(TokenType.OPEN_CURLY_BRACKET)) {
       if (matches4(peek(), TokenType.STRING)) {
         Token afterString = skipStringLiteral(_currentToken.next);
-        if (afterString != null && afterString.type == TokenType.COLON) {
-          return new ExpressionStatement(parseExpression2(), expect2(TokenType.SEMICOLON));
+        if (afterString != null && identical(afterString.type, TokenType.COLON)) {
+          return new ExpressionStatement.full(parseExpression2(), expect2(TokenType.SEMICOLON));
         }
       }
       return parseBlock();
-    } else if (matches5(TokenType.KEYWORD) && !(_currentToken as KeywordToken).keyword.isPseudoKeyword()) {
-      Keyword keyword29 = (_currentToken as KeywordToken).keyword;
-      if (keyword29 == Keyword.ASSERT) {
+    } else if (matches5(TokenType.KEYWORD) && !((_currentToken as KeywordToken)).keyword.isPseudoKeyword()) {
+      Keyword keyword28 = ((_currentToken as KeywordToken)).keyword;
+      if (identical(keyword28, Keyword.ASSERT)) {
         return parseAssertStatement();
-      } else if (keyword29 == Keyword.BREAK) {
+      } else if (identical(keyword28, Keyword.BREAK)) {
         return parseBreakStatement();
-      } else if (keyword29 == Keyword.CONTINUE) {
+      } else if (identical(keyword28, Keyword.CONTINUE)) {
         return parseContinueStatement();
-      } else if (keyword29 == Keyword.DO) {
+      } else if (identical(keyword28, Keyword.DO)) {
         return parseDoStatement();
-      } else if (keyword29 == Keyword.FOR) {
+      } else if (identical(keyword28, Keyword.FOR)) {
         return parseForStatement();
-      } else if (keyword29 == Keyword.IF) {
+      } else if (identical(keyword28, Keyword.IF)) {
         return parseIfStatement();
-      } else if (keyword29 == Keyword.RETURN) {
+      } else if (identical(keyword28, Keyword.RETURN)) {
         return parseReturnStatement();
-      } else if (keyword29 == Keyword.SWITCH) {
+      } else if (identical(keyword28, Keyword.SWITCH)) {
         return parseSwitchStatement();
-      } else if (keyword29 == Keyword.THROW) {
-        return new ExpressionStatement(parseThrowExpression(), expect2(TokenType.SEMICOLON));
-      } else if (keyword29 == Keyword.TRY) {
+      } else if (identical(keyword28, Keyword.THROW)) {
+        return new ExpressionStatement.full(parseThrowExpression(), expect2(TokenType.SEMICOLON));
+      } else if (identical(keyword28, Keyword.TRY)) {
         return parseTryStatement();
-      } else if (keyword29 == Keyword.WHILE) {
+      } else if (identical(keyword28, Keyword.WHILE)) {
         return parseWhileStatement();
-      } else if (keyword29 == Keyword.VAR || keyword29 == Keyword.FINAL) {
+      } else if (identical(keyword28, Keyword.VAR) || identical(keyword28, Keyword.FINAL)) {
         return parseVariableDeclarationStatement();
-      } else if (keyword29 == Keyword.VOID) {
+      } else if (identical(keyword28, Keyword.VOID)) {
         TypeName returnType = parseReturnType();
         if (matchesIdentifier() && matchesAny(peek(), [TokenType.OPEN_PAREN, TokenType.OPEN_CURLY_BRACKET, TokenType.FUNCTION])) {
           return parseFunctionDeclarationStatement2(commentAndMetadata, returnType);
@@ -2910,20 +2910,20 @@
           }
           return null;
         }
-      } else if (keyword29 == Keyword.CONST) {
+      } else if (identical(keyword28, Keyword.CONST)) {
         if (matchesAny(peek(), [TokenType.LT, TokenType.OPEN_CURLY_BRACKET, TokenType.OPEN_SQUARE_BRACKET, TokenType.INDEX])) {
-          return new ExpressionStatement(parseExpression2(), expect2(TokenType.SEMICOLON));
+          return new ExpressionStatement.full(parseExpression2(), expect2(TokenType.SEMICOLON));
         } else if (matches4(peek(), TokenType.IDENTIFIER)) {
           Token afterType = skipTypeName(peek());
           if (afterType != null) {
             if (matches4(afterType, TokenType.OPEN_PAREN) || (matches4(afterType, TokenType.PERIOD) && matches4(afterType.next, TokenType.IDENTIFIER) && matches4(afterType.next.next, TokenType.OPEN_PAREN))) {
-              return new ExpressionStatement(parseExpression2(), expect2(TokenType.SEMICOLON));
+              return new ExpressionStatement.full(parseExpression2(), expect2(TokenType.SEMICOLON));
             }
           }
         }
         return parseVariableDeclarationStatement();
-      } else if (keyword29 == Keyword.NEW || keyword29 == Keyword.TRUE || keyword29 == Keyword.FALSE || keyword29 == Keyword.NULL || keyword29 == Keyword.SUPER || keyword29 == Keyword.THIS) {
-        return new ExpressionStatement(parseExpression2(), expect2(TokenType.SEMICOLON));
+      } else if (identical(keyword28, Keyword.NEW) || identical(keyword28, Keyword.TRUE) || identical(keyword28, Keyword.FALSE) || identical(keyword28, Keyword.NULL) || identical(keyword28, Keyword.SUPER) || identical(keyword28, Keyword.THIS)) {
+        return new ExpressionStatement.full(parseExpression2(), expect2(TokenType.SEMICOLON));
       } else {
         return null;
       }
@@ -2934,7 +2934,7 @@
     } else if (isFunctionDeclaration()) {
       return parseFunctionDeclarationStatement();
     } else {
-      return new ExpressionStatement(parseExpression2(), expect2(TokenType.SEMICOLON));
+      return new ExpressionStatement.full(parseExpression2(), expect2(TokenType.SEMICOLON));
     }
   }
   /**
@@ -2968,16 +2968,16 @@
       if (thisKeyword != null) {
       }
       FormalParameterList parameters = parseFormalParameterList();
-      return new FunctionTypedFormalParameter(commentAndMetadata.comment, commentAndMetadata.metadata, holder.type, identifier, parameters);
+      return new FunctionTypedFormalParameter.full(commentAndMetadata.comment, commentAndMetadata.metadata, holder.type, identifier, parameters);
     }
-    TypeName type18 = holder.type;
-    if (type18 != null && matches3(type18.name.beginToken, Keyword.VOID)) {
-      reportError4(ParserErrorCode.VOID_PARAMETER, type18.name.beginToken, []);
+    TypeName type16 = holder.type;
+    if (type16 != null && matches3(type16.name.beginToken, Keyword.VOID)) {
+      reportError4(ParserErrorCode.VOID_PARAMETER, type16.name.beginToken, []);
     }
     if (thisKeyword != null) {
-      return new FieldFormalParameter(commentAndMetadata.comment, commentAndMetadata.metadata, holder.keyword, holder.type, thisKeyword, period, identifier);
+      return new FieldFormalParameter.full(commentAndMetadata.comment, commentAndMetadata.metadata, holder.keyword, holder.type, thisKeyword, period, identifier);
     }
-    return new SimpleFormalParameter(commentAndMetadata.comment, commentAndMetadata.metadata, holder.keyword, holder.type, identifier);
+    return new SimpleFormalParameter.full(commentAndMetadata.comment, commentAndMetadata.metadata, holder.keyword, holder.type, identifier);
   }
   /**
    * Parse an operator declaration.
@@ -2999,14 +2999,14 @@
     if (!_currentToken.isUserDefinableOperator()) {
       reportError3(ParserErrorCode.NON_USER_DEFINABLE_OPERATOR, [_currentToken.lexeme]);
     }
-    SimpleIdentifier name = new SimpleIdentifier(andAdvance);
+    SimpleIdentifier name = new SimpleIdentifier.full(andAdvance);
     FormalParameterList parameters = parseFormalParameterList();
     validateFormalParameterList(parameters);
     FunctionBody body = parseFunctionBody(true, false);
     if (externalKeyword != null && body is! EmptyFunctionBody) {
       reportError3(ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY, []);
     }
-    return new MethodDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, null, returnType, null, operatorKeyword, name, parameters, body);
+    return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, null, returnType, null, operatorKeyword, name, parameters, body);
   }
   /**
    * Parse a return type if one is given, otherwise return {@code null} without advancing.
@@ -3035,15 +3035,15 @@
    */
   Directive parsePartDirective(CommentAndMetadata commentAndMetadata) {
     Token partKeyword = expect(Keyword.PART);
-    if (matches2(Parser._OF)) {
+    if (matches2(_OF)) {
       Token ofKeyword = andAdvance;
       LibraryIdentifier libraryName = parseLibraryName(ParserErrorCode.MISSING_NAME_IN_PART_OF_DIRECTIVE, ofKeyword);
       Token semicolon = expect2(TokenType.SEMICOLON);
-      return new PartOfDirective(commentAndMetadata.comment, commentAndMetadata.metadata, partKeyword, ofKeyword, libraryName, semicolon);
+      return new PartOfDirective.full(commentAndMetadata.comment, commentAndMetadata.metadata, partKeyword, ofKeyword, libraryName, semicolon);
     }
     StringLiteral partUri = parseStringLiteral();
     Token semicolon = expect2(TokenType.SEMICOLON);
-    return new PartDirective(commentAndMetadata.comment, commentAndMetadata.metadata, partKeyword, partUri, semicolon);
+    return new PartDirective.full(commentAndMetadata.comment, commentAndMetadata.metadata, partKeyword, partUri, semicolon);
   }
   /**
    * Parse a postfix expression.
@@ -3064,10 +3064,10 @@
         if (matches5(TokenType.OPEN_PAREN)) {
           ArgumentList argumentList = parseArgumentList();
           if (operand is PropertyAccess) {
-            PropertyAccess access = operand as PropertyAccess;
-            operand = new MethodInvocation(access.target, access.operator, access.propertyName, argumentList);
+            PropertyAccess access = (operand as PropertyAccess);
+            operand = new MethodInvocation.full(access.target, access.operator, access.propertyName, argumentList);
           } else {
-            operand = new FunctionExpressionInvocation(operand, argumentList);
+            operand = new FunctionExpressionInvocation.full(operand, argumentList);
           }
         } else {
           operand = parseAssignableSelector(operand, true);
@@ -3082,7 +3082,7 @@
       reportError3(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []);
     }
     Token operator = andAdvance;
-    return new PostfixExpression(operand, operator);
+    return new PostfixExpression.full(operand, operator);
   }
   /**
    * Parse a prefixed identifier.
@@ -3099,7 +3099,7 @@
     }
     Token period = andAdvance;
     SimpleIdentifier qualified = parseSimpleIdentifier();
-    return new PrefixedIdentifier(qualifier, period, qualified);
+    return new PrefixedIdentifier.full(qualifier, period, qualified);
   }
   /**
    * Parse a primary expression.
@@ -3126,15 +3126,15 @@
    */
   Expression parsePrimaryExpression() {
     if (matches(Keyword.THIS)) {
-      return new ThisExpression(andAdvance);
+      return new ThisExpression.full(andAdvance);
     } else if (matches(Keyword.SUPER)) {
-      return parseAssignableSelector(new SuperExpression(andAdvance), false);
+      return parseAssignableSelector(new SuperExpression.full(andAdvance), false);
     } else if (matches(Keyword.NULL)) {
-      return new NullLiteral(andAdvance);
+      return new NullLiteral.full(andAdvance);
     } else if (matches(Keyword.FALSE)) {
-      return new BooleanLiteral(andAdvance, false);
+      return new BooleanLiteral.full(andAdvance, false);
     } else if (matches(Keyword.TRUE)) {
-      return new BooleanLiteral(andAdvance, true);
+      return new BooleanLiteral.full(andAdvance, true);
     } else if (matches5(TokenType.DOUBLE)) {
       Token token = andAdvance;
       double value = 0.0;
@@ -3142,7 +3142,7 @@
         value = double.parse(token.lexeme);
       } on NumberFormatException catch (exception) {
       }
-      return new DoubleLiteral(token, value);
+      return new DoubleLiteral.full(token, value);
     } else if (matches5(TokenType.HEXADECIMAL)) {
       Token token = andAdvance;
       int value = null;
@@ -3150,7 +3150,7 @@
         value = int.parse(token.lexeme.substring(2), radix: 16);
       } on NumberFormatException catch (exception) {
       }
-      return new IntegerLiteral.con1(token, value);
+      return new IntegerLiteral.full(token, value);
     } else if (matches5(TokenType.INT)) {
       Token token = andAdvance;
       int value = null;
@@ -3158,7 +3158,7 @@
         value = int.parse(token.lexeme);
       } on NumberFormatException catch (exception) {
       }
-      return new IntegerLiteral.con1(token, value);
+      return new IntegerLiteral.full(token, value);
     } else if (matches5(TokenType.STRING)) {
       return parseStringLiteral();
     } else if (matches5(TokenType.OPEN_CURLY_BRACKET)) {
@@ -3178,7 +3178,7 @@
       Token leftParenthesis = andAdvance;
       Expression expression = parseExpression2();
       Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
-      return new ParenthesizedExpression(leftParenthesis, expression, rightParenthesis);
+      return new ParenthesizedExpression.full(leftParenthesis, expression, rightParenthesis);
     } else if (matches5(TokenType.LT)) {
       return parseListOrMapLiteral(null);
     } else if (matches5(TokenType.QUESTION)) {
@@ -3208,7 +3208,7 @@
       constructorName = parseSimpleIdentifier();
     }
     ArgumentList argumentList = parseArgumentList();
-    return new RedirectingConstructorInvocation(keyword, period, constructorName, argumentList);
+    return new RedirectingConstructorInvocation.full(keyword, period, constructorName, argumentList);
   }
   /**
    * Parse a relational expression.
@@ -3221,25 +3221,25 @@
    */
   Expression parseRelationalExpression() {
     if (matches(Keyword.SUPER) && _currentToken.next.type.isRelationalOperator()) {
-      Expression expression = new SuperExpression(andAdvance);
+      Expression expression = new SuperExpression.full(andAdvance);
       Token operator = andAdvance;
-      expression = new BinaryExpression(expression, operator, parseShiftExpression());
+      expression = new BinaryExpression.full(expression, operator, parseShiftExpression());
       return expression;
     }
     Expression expression = parseShiftExpression();
     if (matches(Keyword.AS)) {
       Token isOperator = andAdvance;
-      expression = new AsExpression(expression, isOperator, parseTypeName());
+      expression = new AsExpression.full(expression, isOperator, parseTypeName());
     } else if (matches(Keyword.IS)) {
       Token isOperator = andAdvance;
       Token notOperator = null;
       if (matches5(TokenType.BANG)) {
         notOperator = andAdvance;
       }
-      expression = new IsExpression(expression, isOperator, notOperator, parseTypeName());
+      expression = new IsExpression.full(expression, isOperator, notOperator, parseTypeName());
     } else if (_currentToken.type.isRelationalOperator()) {
       Token operator = andAdvance;
-      expression = new BinaryExpression(expression, operator, parseShiftExpression());
+      expression = new BinaryExpression.full(expression, operator, parseShiftExpression());
     }
     return expression;
   }
@@ -3254,11 +3254,11 @@
   Statement parseReturnStatement() {
     Token returnKeyword = expect(Keyword.RETURN);
     if (matches5(TokenType.SEMICOLON)) {
-      return new ReturnStatement(returnKeyword, null, andAdvance);
+      return new ReturnStatement.full(returnKeyword, null, andAdvance);
     }
     Expression expression = parseExpression2();
     Token semicolon = expect2(TokenType.SEMICOLON);
-    return new ReturnStatement(returnKeyword, expression, semicolon);
+    return new ReturnStatement.full(returnKeyword, expression, semicolon);
   }
   /**
    * Parse a return type.
@@ -3271,7 +3271,7 @@
    */
   TypeName parseReturnType() {
     if (matches(Keyword.VOID)) {
-      return new TypeName(new SimpleIdentifier(andAdvance), null);
+      return new TypeName.full(new SimpleIdentifier.full(andAdvance), null);
     } else {
       return parseTypeName();
     }
@@ -3301,7 +3301,7 @@
     if (externalKeyword != null && body is! EmptyFunctionBody) {
       reportError3(ParserErrorCode.EXTERNAL_SETTER_WITH_BODY, []);
     }
-    return new MethodDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, staticKeyword, returnType, propertyKeyword, null, name, parameters, body);
+    return new MethodDeclaration.full(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, staticKeyword, returnType, propertyKeyword, null, name, parameters, body);
   }
   /**
    * Parse a shift expression.
@@ -3315,13 +3315,13 @@
   Expression parseShiftExpression() {
     Expression expression;
     if (matches(Keyword.SUPER) && _currentToken.next.type.isShiftOperator()) {
-      expression = new SuperExpression(andAdvance);
+      expression = new SuperExpression.full(andAdvance);
     } else {
       expression = parseAdditiveExpression();
     }
     while (_currentToken.type.isShiftOperator()) {
       Token operator = andAdvance;
-      expression = new BinaryExpression(expression, operator, parseAdditiveExpression());
+      expression = new BinaryExpression.full(expression, operator, parseAdditiveExpression());
     }
     return expression;
   }
@@ -3335,7 +3335,7 @@
    */
   SimpleIdentifier parseSimpleIdentifier() {
     if (matchesIdentifier()) {
-      return new SimpleIdentifier(andAdvance);
+      return new SimpleIdentifier.full(andAdvance);
     }
     reportError3(ParserErrorCode.MISSING_IDENTIFIER, []);
     return createSyntheticIdentifier();
@@ -3352,10 +3352,10 @@
   SimpleIdentifier parseSimpleIdentifier2(ParserErrorCode errorCode) {
     if (matchesIdentifier()) {
       Token token = andAdvance;
-      if (token.type == TokenType.KEYWORD) {
+      if (identical(token.type, TokenType.KEYWORD)) {
         reportError4(errorCode, token, [token.lexeme]);
       }
-      return new SimpleIdentifier(token);
+      return new SimpleIdentifier.full(token);
     }
     reportError3(ParserErrorCode.MISSING_IDENTIFIER, []);
     return createSyntheticIdentifier();
@@ -3373,13 +3373,13 @@
     while (matchesIdentifier() && matches4(peek(), TokenType.COLON)) {
       SimpleIdentifier label = parseSimpleIdentifier();
       Token colon = expect2(TokenType.COLON);
-      labels.add(new Label(label, colon));
+      labels.add(new Label.full(label, colon));
     }
     Statement statement = parseNonLabeledStatement();
     if (labels.isEmpty) {
       return statement;
     }
-    return new LabeledStatement(labels, statement);
+    return new LabeledStatement.full(labels, statement);
   }
   /**
    * Parse a list of statements within a switch statement.
@@ -3394,7 +3394,7 @@
     Token statementStart = _currentToken;
     while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET) && !isSwitchMember()) {
       statements.add(parseStatement2());
-      if (_currentToken == statementStart) {
+      if (identical(_currentToken, statementStart)) {
         reportError4(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
         advance();
       }
@@ -3408,29 +3408,29 @@
    */
   StringInterpolation parseStringInterpolation(Token string) {
     List<InterpolationElement> elements = new List<InterpolationElement>();
-    elements.add(new InterpolationString(string, computeStringValue(string.lexeme)));
+    elements.add(new InterpolationString.full(string, computeStringValue(string.lexeme)));
     while (matches5(TokenType.STRING_INTERPOLATION_EXPRESSION) || matches5(TokenType.STRING_INTERPOLATION_IDENTIFIER)) {
       if (matches5(TokenType.STRING_INTERPOLATION_EXPRESSION)) {
         Token openToken = andAdvance;
         Expression expression = parseExpression2();
         Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET);
-        elements.add(new InterpolationExpression(openToken, expression, rightBracket));
+        elements.add(new InterpolationExpression.full(openToken, expression, rightBracket));
       } else {
         Token openToken = andAdvance;
         Expression expression = null;
         if (matches(Keyword.THIS)) {
-          expression = new ThisExpression(andAdvance);
+          expression = new ThisExpression.full(andAdvance);
         } else {
           expression = parseSimpleIdentifier();
         }
-        elements.add(new InterpolationExpression(openToken, expression, null));
+        elements.add(new InterpolationExpression.full(openToken, expression, null));
       }
       if (matches5(TokenType.STRING)) {
         string = andAdvance;
-        elements.add(new InterpolationString(string, computeStringValue(string.lexeme)));
+        elements.add(new InterpolationString.full(string, computeStringValue(string.lexeme)));
       }
     }
-    return new StringInterpolation(elements);
+    return new StringInterpolation.full(elements);
   }
   /**
    * Parse a string literal.
@@ -3448,7 +3448,7 @@
       if (matches5(TokenType.STRING_INTERPOLATION_EXPRESSION) || matches5(TokenType.STRING_INTERPOLATION_IDENTIFIER)) {
         strings.add(parseStringInterpolation(string));
       } else {
-        strings.add(new SimpleStringLiteral(string, computeStringValue(string.lexeme)));
+        strings.add(new SimpleStringLiteral.full(string, computeStringValue(string.lexeme)));
       }
     }
     if (strings.length < 1) {
@@ -3457,7 +3457,7 @@
     } else if (strings.length == 1) {
       return strings[0];
     } else {
-      return new AdjacentStrings(strings);
+      return new AdjacentStrings.full(strings);
     }
   }
   /**
@@ -3477,7 +3477,7 @@
       constructorName = parseSimpleIdentifier();
     }
     ArgumentList argumentList = parseArgumentList();
-    return new SuperConstructorInvocation(keyword, period, constructorName, argumentList);
+    return new SuperConstructorInvocation.full(keyword, period, constructorName, argumentList);
   }
   /**
    * Parse a switch statement.
@@ -3513,17 +3513,17 @@
             javaSetAdd(definedLabels, label);
           }
           Token colon = expect2(TokenType.COLON);
-          labels.add(new Label(identifier, colon));
+          labels.add(new Label.full(identifier, colon));
         }
         if (matches(Keyword.CASE)) {
           Token caseKeyword = andAdvance;
           Expression caseExpression = parseExpression2();
           Token colon = expect2(TokenType.COLON);
-          members.add(new SwitchCase(labels, caseKeyword, caseExpression, colon, parseStatements2()));
+          members.add(new SwitchCase.full(labels, caseKeyword, caseExpression, colon, parseStatements2()));
         } else if (matches(Keyword.DEFAULT)) {
           Token defaultKeyword = andAdvance;
           Token colon = expect2(TokenType.COLON);
-          members.add(new SwitchDefault(labels, defaultKeyword, colon, parseStatements2()));
+          members.add(new SwitchDefault.full(labels, defaultKeyword, colon, parseStatements2()));
         } else {
           reportError3(ParserErrorCode.EXPECTED_CASE_OR_DEFAULT, []);
           while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET) && !matches(Keyword.CASE) && !matches(Keyword.DEFAULT)) {
@@ -3532,7 +3532,7 @@
         }
       }
       Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET);
-      return new SwitchStatement(keyword, leftParenthesis, expression, rightParenthesis, leftBracket, members, rightBracket);
+      return new SwitchStatement.full(keyword, leftParenthesis, expression, rightParenthesis, leftBracket, members, rightBracket);
     } finally {
       _inSwitch = wasInSwitch;
     }
@@ -3548,10 +3548,10 @@
   Expression parseThrowExpression() {
     Token keyword = expect(Keyword.THROW);
     if (matches5(TokenType.SEMICOLON) || matches5(TokenType.CLOSE_PAREN)) {
-      return new ThrowExpression(keyword, null);
+      return new ThrowExpression.full(keyword, null);
     }
     Expression expression = parseExpression2();
-    return new ThrowExpression(keyword, expression);
+    return new ThrowExpression.full(keyword, expression);
   }
   /**
    * Parse a throw expression.
@@ -3564,10 +3564,10 @@
   Expression parseThrowExpressionWithoutCascade() {
     Token keyword = expect(Keyword.THROW);
     if (matches5(TokenType.SEMICOLON) || matches5(TokenType.CLOSE_PAREN)) {
-      return new ThrowExpression(keyword, null);
+      return new ThrowExpression.full(keyword, null);
     }
     Expression expression = parseExpressionWithoutCascade();
-    return new ThrowExpression(keyword, expression);
+    return new ThrowExpression.full(keyword, expression);
   }
   /**
    * Parse a try statement.
@@ -3589,12 +3589,12 @@
     Block body = parseBlock();
     List<CatchClause> catchClauses = new List<CatchClause>();
     Block finallyClause = null;
-    while (matches2(Parser._ON) || matches(Keyword.CATCH)) {
+    while (matches2(_ON) || matches(Keyword.CATCH)) {
       Token onKeyword = null;
       TypeName exceptionType = null;
-      if (matches2(Parser._ON)) {
+      if (matches2(_ON)) {
         onKeyword = andAdvance;
-        exceptionType = new TypeName(parsePrefixedIdentifier(), null);
+        exceptionType = new TypeName.full(parsePrefixedIdentifier(), null);
       }
       Token catchKeyword = null;
       Token leftParenthesis = null;
@@ -3613,7 +3613,7 @@
         rightParenthesis = expect2(TokenType.CLOSE_PAREN);
       }
       Block catchBody = parseBlock();
-      catchClauses.add(new CatchClause(onKeyword, exceptionType, catchKeyword, leftParenthesis, exceptionParameter, comma, stackTraceParameter, rightParenthesis, catchBody));
+      catchClauses.add(new CatchClause.full(onKeyword, exceptionType, catchKeyword, leftParenthesis, exceptionParameter, comma, stackTraceParameter, rightParenthesis, catchBody));
     }
     Token finallyKeyword = null;
     if (matches(Keyword.FINALLY)) {
@@ -3624,7 +3624,7 @@
         reportError3(ParserErrorCode.MISSING_CATCH_OR_FINALLY, []);
       }
     }
-    return new TryStatement(tryKeyword, body, catchClauses, finallyKeyword, finallyClause);
+    return new TryStatement.full(tryKeyword, body, catchClauses, finallyKeyword, finallyClause);
   }
   /**
    * Parse a type alias.
@@ -3679,7 +3679,7 @@
       arguments.add(parseTypeName());
     }
     Token rightBracket = expect2(TokenType.GT);
-    return new TypeArgumentList(leftBracket, arguments, rightBracket);
+    return new TypeArgumentList.full(leftBracket, arguments, rightBracket);
   }
   /**
    * Parse a type name.
@@ -3695,7 +3695,7 @@
     if (matches5(TokenType.LT)) {
       typeArguments = parseTypeArgumentList();
     }
-    return new TypeName(typeName, typeArguments);
+    return new TypeName.full(typeName, typeArguments);
   }
   /**
    * Parse a type parameter.
@@ -3711,9 +3711,9 @@
     if (matches(Keyword.EXTENDS)) {
       Token keyword = andAdvance;
       TypeName bound = parseTypeName();
-      return new TypeParameter(commentAndMetadata.comment, commentAndMetadata.metadata, name, keyword, bound);
+      return new TypeParameter.full(commentAndMetadata.comment, commentAndMetadata.metadata, name, keyword, bound);
     }
-    return new TypeParameter(commentAndMetadata.comment, commentAndMetadata.metadata, name, null, null);
+    return new TypeParameter.full(commentAndMetadata.comment, commentAndMetadata.metadata, name, null, null);
   }
   /**
    * Parse a list of type parameters.
@@ -3731,7 +3731,7 @@
       typeParameters.add(parseTypeParameter());
     }
     Token rightBracket = expect2(TokenType.GT);
-    return new TypeParameterList(leftBracket, typeParameters, rightBracket);
+    return new TypeParameterList.full(leftBracket, typeParameters, rightBracket);
   }
   /**
    * Parse a unary expression.
@@ -3750,28 +3750,28 @@
       Token operator = andAdvance;
       if (matches(Keyword.SUPER)) {
         if (matches4(peek(), TokenType.OPEN_SQUARE_BRACKET) || matches4(peek(), TokenType.PERIOD)) {
-          return new PrefixExpression(operator, parseUnaryExpression());
+          return new PrefixExpression.full(operator, parseUnaryExpression());
         }
-        return new PrefixExpression(operator, new SuperExpression(andAdvance));
+        return new PrefixExpression.full(operator, new SuperExpression.full(andAdvance));
       }
-      return new PrefixExpression(operator, parseUnaryExpression());
+      return new PrefixExpression.full(operator, parseUnaryExpression());
     } else if (_currentToken.type.isIncrementOperator()) {
       Token operator = andAdvance;
       if (matches(Keyword.SUPER)) {
-        if (operator.type == TokenType.MINUS_MINUS) {
-          int offset7 = operator.offset;
-          Token firstOperator = new Token(TokenType.MINUS, offset7);
-          Token secondOperator = new Token(TokenType.MINUS, offset7 + 1);
+        if (identical(operator.type, TokenType.MINUS_MINUS)) {
+          int offset8 = operator.offset;
+          Token firstOperator = new Token(TokenType.MINUS, offset8);
+          Token secondOperator = new Token(TokenType.MINUS, offset8 + 1);
           secondOperator.setNext(_currentToken);
           firstOperator.setNext(secondOperator);
           operator.previous.setNext(firstOperator);
-          return new PrefixExpression(firstOperator, new PrefixExpression(secondOperator, new SuperExpression(andAdvance)));
+          return new PrefixExpression.full(firstOperator, new PrefixExpression.full(secondOperator, new SuperExpression.full(andAdvance)));
         } else {
           reportError3(ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, [operator.lexeme]);
-          return new PrefixExpression(operator, new SuperExpression(andAdvance));
+          return new PrefixExpression.full(operator, new SuperExpression.full(andAdvance));
         }
       }
-      return new PrefixExpression(operator, parseAssignableExpression(false));
+      return new PrefixExpression.full(operator, parseAssignableExpression(false));
     } else if (matches5(TokenType.PLUS)) {
       reportError3(ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR, []);
     }
@@ -3794,7 +3794,7 @@
       equals = andAdvance;
       initializer = parseExpression2();
     }
-    return new VariableDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, name, equals, initializer);
+    return new VariableDeclaration.full(commentAndMetadata.comment, commentAndMetadata.metadata, name, equals, initializer);
   }
   /**
    * Parse a variable declaration list.
@@ -3826,7 +3826,7 @@
       advance();
       variables.add(parseVariableDeclaration());
     }
-    return new VariableDeclarationList(keyword, type, variables);
+    return new VariableDeclarationList.full(keyword, type, variables);
   }
   /**
    * Parse a variable declaration statement.
@@ -3839,7 +3839,7 @@
   VariableDeclarationStatement parseVariableDeclarationStatement() {
     VariableDeclarationList variableList = parseVariableDeclarationList();
     Token semicolon = expect2(TokenType.SEMICOLON);
-    return new VariableDeclarationStatement(variableList, semicolon);
+    return new VariableDeclarationStatement.full(variableList, semicolon);
   }
   /**
    * Parse a while statement.
@@ -3858,7 +3858,7 @@
       Expression condition = parseExpression2();
       Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
       Statement body = parseStatement2();
-      return new WhileStatement(keyword, leftParenthesis, condition, rightParenthesis, body);
+      return new WhileStatement.full(keyword, leftParenthesis, condition, rightParenthesis, body);
     } finally {
       _inLoop = wasInLoop;
     }
@@ -3878,7 +3878,7 @@
     while (optional(TokenType.COMMA)) {
       types.add(parseTypeName());
     }
-    return new WithClause(with6, types);
+    return new WithClause.full(with6, types);
   }
   /**
    * Return the token that is immediately after the current token. This is equivalent to{@link #peek(int) peek(1)}.
@@ -3940,15 +3940,15 @@
    */
   Token skipFinalConstVarOrType(Token startToken) {
     if (matches3(startToken, Keyword.FINAL) || matches3(startToken, Keyword.CONST)) {
-      Token next2 = startToken.next;
-      if (matchesIdentifier2(next2.next) || matches4(next2.next, TokenType.LT) || matches3(next2.next, Keyword.THIS)) {
-        return skipTypeName(next2);
+      Token next3 = startToken.next;
+      if (matchesIdentifier2(next3.next) || matches4(next3.next, TokenType.LT) || matches3(next3.next, Keyword.THIS)) {
+        return skipTypeName(next3);
       }
     } else if (matches3(startToken, Keyword.VAR)) {
       return startToken.next;
     } else if (matchesIdentifier2(startToken)) {
-      Token next3 = startToken.next;
-      if (matchesIdentifier2(next3) || matches4(next3, TokenType.LT) || matches3(next3, Keyword.THIS) || (matches4(next3, TokenType.PERIOD) && matchesIdentifier2(next3.next) && (matchesIdentifier2(next3.next.next) || matches4(next3.next.next, TokenType.LT) || matches3(next3.next.next, Keyword.THIS)))) {
+      Token next4 = startToken.next;
+      if (matchesIdentifier2(next4) || matches4(next4, TokenType.LT) || matches3(next4, Keyword.THIS) || (matches4(next4, TokenType.PERIOD) && matchesIdentifier2(next4.next) && (matchesIdentifier2(next4.next.next) || matches4(next4.next.next, TokenType.LT) || matches3(next4.next.next, Keyword.THIS)))) {
         return skipReturnType(startToken);
       }
     }
@@ -3989,20 +3989,20 @@
     if (!matches4(startToken, TokenType.OPEN_PAREN)) {
       return null;
     }
-    Token next4 = startToken.next;
-    if (matches4(next4, TokenType.CLOSE_PAREN)) {
-      return next4.next;
+    Token next5 = startToken.next;
+    if (matches4(next5, TokenType.CLOSE_PAREN)) {
+      return next5.next;
     }
-    if (matchesAny(next4, [TokenType.AT, TokenType.OPEN_SQUARE_BRACKET, TokenType.OPEN_CURLY_BRACKET]) || matches3(next4, Keyword.VOID) || (matchesIdentifier2(next4) && (matchesAny(next4.next, [TokenType.COMMA, TokenType.CLOSE_PAREN])))) {
+    if (matchesAny(next5, [TokenType.AT, TokenType.OPEN_SQUARE_BRACKET, TokenType.OPEN_CURLY_BRACKET]) || matches3(next5, Keyword.VOID) || (matchesIdentifier2(next5) && (matchesAny(next5.next, [TokenType.COMMA, TokenType.CLOSE_PAREN])))) {
       return skipPastMatchingToken(startToken);
     }
-    if (matchesIdentifier2(next4) && matches4(next4.next, TokenType.OPEN_PAREN)) {
-      Token afterParameters = skipFormalParameterList(next4.next);
+    if (matchesIdentifier2(next5) && matches4(next5.next, TokenType.OPEN_PAREN)) {
+      Token afterParameters = skipFormalParameterList(next5.next);
       if (afterParameters != null && (matchesAny(afterParameters, [TokenType.COMMA, TokenType.CLOSE_PAREN]))) {
         return skipPastMatchingToken(startToken);
       }
     }
-    Token afterType = skipFinalConstVarOrType(next4);
+    Token afterType = skipFinalConstVarOrType(next5);
     if (afterType == null) {
       return null;
     }
@@ -4021,7 +4021,7 @@
     if (startToken is! BeginToken) {
       return null;
     }
-    Token closeParen = (startToken as BeginToken).endToken;
+    Token closeParen = ((startToken as BeginToken)).endToken;
     if (closeParen == null) {
       return null;
     }
@@ -4085,7 +4085,7 @@
    * @return the token following the simple identifier that was parsed
    */
   Token skipSimpleIdentifier(Token startToken) {
-    if (matches4(startToken, TokenType.IDENTIFIER) || (matches4(startToken, TokenType.KEYWORD) && (startToken as KeywordToken).keyword.isPseudoKeyword())) {
+    if (matches4(startToken, TokenType.IDENTIFIER) || (matches4(startToken, TokenType.KEYWORD) && ((startToken as KeywordToken)).keyword.isPseudoKeyword())) {
       return startToken.next;
     }
     return null;
@@ -4102,20 +4102,20 @@
    */
   Token skipStringInterpolation(Token startToken) {
     Token token = startToken;
-    TokenType type19 = token.type;
-    while (type19 == TokenType.STRING_INTERPOLATION_EXPRESSION || type19 == TokenType.STRING_INTERPOLATION_IDENTIFIER) {
-      if (type19 == TokenType.STRING_INTERPOLATION_EXPRESSION) {
+    TokenType type17 = token.type;
+    while (identical(type17, TokenType.STRING_INTERPOLATION_EXPRESSION) || identical(type17, TokenType.STRING_INTERPOLATION_IDENTIFIER)) {
+      if (identical(type17, TokenType.STRING_INTERPOLATION_EXPRESSION)) {
         token = token.next;
-        type19 = token.type;
+        type17 = token.type;
         int bracketNestingLevel = 1;
         while (bracketNestingLevel > 0) {
-          if (type19 == TokenType.EOF) {
+          if (identical(type17, TokenType.EOF)) {
             return null;
-          } else if (type19 == TokenType.OPEN_CURLY_BRACKET) {
+          } else if (identical(type17, TokenType.OPEN_CURLY_BRACKET)) {
             bracketNestingLevel++;
-          } else if (type19 == TokenType.CLOSE_CURLY_BRACKET) {
+          } else if (identical(type17, TokenType.CLOSE_CURLY_BRACKET)) {
             bracketNestingLevel--;
-          } else if (type19 == TokenType.STRING) {
+          } else if (identical(type17, TokenType.STRING)) {
             token = skipStringLiteral(token);
             if (token == null) {
               return null;
@@ -4123,10 +4123,10 @@
           } else {
             token = token.next;
           }
-          type19 = token.type;
+          type17 = token.type;
         }
         token = token.next;
-        type19 = token.type;
+        type17 = token.type;
       } else {
         token = token.next;
         if (token.type != TokenType.IDENTIFIER) {
@@ -4134,10 +4134,10 @@
         }
         token = token.next;
       }
-      type19 = token.type;
-      if (type19 == TokenType.STRING) {
+      type17 = token.type;
+      if (identical(type17, TokenType.STRING)) {
         token = token.next;
-        type19 = token.type;
+        type17 = token.type;
       }
     }
     return token;
@@ -4160,12 +4160,12 @@
     Token token = startToken;
     while (token != null && matches4(token, TokenType.STRING)) {
       token = token.next;
-      TokenType type20 = token.type;
-      if (type20 == TokenType.STRING_INTERPOLATION_EXPRESSION || type20 == TokenType.STRING_INTERPOLATION_IDENTIFIER) {
+      TokenType type18 = token.type;
+      if (identical(type18, TokenType.STRING_INTERPOLATION_EXPRESSION) || identical(type18, TokenType.STRING_INTERPOLATION_IDENTIFIER)) {
         token = skipStringInterpolation(token);
       }
     }
-    if (token == startToken) {
+    if (identical(token, startToken)) {
       return null;
     }
     return token;
@@ -4200,9 +4200,9 @@
         return null;
       }
     }
-    if (token.type == TokenType.GT) {
+    if (identical(token.type, TokenType.GT)) {
       return token.next;
-    } else if (token.type == TokenType.GT_GT) {
+    } else if (identical(token.type, TokenType.GT_GT)) {
       Token second = new Token(TokenType.GT, token.offset + 1);
       second.setNextWithoutSettingPrevious(token.next);
       return second;
@@ -4250,36 +4250,36 @@
       return null;
     }
     int depth = 1;
-    Token next5 = startToken.next;
+    Token next6 = startToken.next;
     while (depth > 0) {
-      if (matches4(next5, TokenType.EOF)) {
+      if (matches4(next6, TokenType.EOF)) {
         return null;
-      } else if (matches4(next5, TokenType.LT)) {
+      } else if (matches4(next6, TokenType.LT)) {
         depth++;
-      } else if (matches4(next5, TokenType.GT)) {
+      } else if (matches4(next6, TokenType.GT)) {
         depth--;
-      } else if (matches4(next5, TokenType.GT_EQ)) {
+      } else if (matches4(next6, TokenType.GT_EQ)) {
         if (depth == 1) {
-          Token fakeEquals = new Token(TokenType.EQ, next5.offset + 2);
-          fakeEquals.setNextWithoutSettingPrevious(next5.next);
+          Token fakeEquals = new Token(TokenType.EQ, next6.offset + 2);
+          fakeEquals.setNextWithoutSettingPrevious(next6.next);
           return fakeEquals;
         }
         depth--;
-      } else if (matches4(next5, TokenType.GT_GT)) {
+      } else if (matches4(next6, TokenType.GT_GT)) {
         depth -= 2;
-      } else if (matches4(next5, TokenType.GT_GT_EQ)) {
+      } else if (matches4(next6, TokenType.GT_GT_EQ)) {
         if (depth < 2) {
           return null;
         } else if (depth == 2) {
-          Token fakeEquals = new Token(TokenType.EQ, next5.offset + 2);
-          fakeEquals.setNextWithoutSettingPrevious(next5.next);
+          Token fakeEquals = new Token(TokenType.EQ, next6.offset + 2);
+          fakeEquals.setNextWithoutSettingPrevious(next6.next);
           return fakeEquals;
         }
         depth -= 2;
       }
-      next5 = next5.next;
+      next6 = next6.next;
     }
-    return next5;
+    return next6;
   }
   /**
    * Translate the characters at the given index in the given string, appending the translated
@@ -4290,8 +4290,8 @@
    * @return the index of the next character to be translated
    */
   int translateCharacter(StringBuffer builder, String lexeme, int index) {
-    int currentChar = lexeme.charCodeAt(index);
-    if (currentChar != 0x5c) {
+    int currentChar = lexeme.codeUnitAt(index);
+    if (currentChar != 0x5C) {
       builder.addCharCode(currentChar);
       return index + 1;
     }
@@ -4300,30 +4300,30 @@
     if (currentIndex >= length8) {
       return length8;
     }
-    currentChar = lexeme.charCodeAt(currentIndex);
-    if (currentChar == 0x6e) {
-      builder.addCharCode(0xa);
+    currentChar = lexeme.codeUnitAt(currentIndex);
+    if (currentChar == 0x6E) {
+      builder.addCharCode(0xA);
     } else if (currentChar == 0x72) {
-      builder.addCharCode(0xd);
+      builder.addCharCode(0xD);
     } else if (currentChar == 0x66) {
-      builder.addCharCode(0xc);
+      builder.addCharCode(0xC);
     } else if (currentChar == 0x62) {
       builder.addCharCode(0x8);
     } else if (currentChar == 0x74) {
       builder.addCharCode(0x9);
     } else if (currentChar == 0x76) {
-      builder.addCharCode(0xb);
+      builder.addCharCode(0xB);
     } else if (currentChar == 0x78) {
       if (currentIndex + 2 >= length8) {
         reportError3(ParserErrorCode.INVALID_HEX_ESCAPE, []);
         return length8;
       }
-      int firstDigit = lexeme.charCodeAt(currentIndex + 1);
-      int secondDigit = lexeme.charCodeAt(currentIndex + 2);
+      int firstDigit = lexeme.codeUnitAt(currentIndex + 1);
+      int secondDigit = lexeme.codeUnitAt(currentIndex + 2);
       if (!isHexDigit(firstDigit) || !isHexDigit(secondDigit)) {
         reportError3(ParserErrorCode.INVALID_HEX_ESCAPE, []);
       } else {
-        builder.addCharCode(((Character.digit(firstDigit, 16) << 4) + Character.digit(secondDigit, 16)) as int);
+        builder.addCharCode((((Character.digit(firstDigit, 16) << 4) + Character.digit(secondDigit, 16)) as int));
       }
       return currentIndex + 3;
     } else if (currentChar == 0x75) {
@@ -4332,21 +4332,21 @@
         reportError3(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
         return length8;
       }
-      currentChar = lexeme.charCodeAt(currentIndex);
-      if (currentChar == 0x7b) {
+      currentChar = lexeme.codeUnitAt(currentIndex);
+      if (currentChar == 0x7B) {
         currentIndex++;
         if (currentIndex >= length8) {
           reportError3(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
           return length8;
         }
-        currentChar = lexeme.charCodeAt(currentIndex);
+        currentChar = lexeme.codeUnitAt(currentIndex);
         int digitCount = 0;
         int value = 0;
-        while (currentChar != 0x7d) {
+        while (currentChar != 0x7D) {
           if (!isHexDigit(currentChar)) {
             reportError3(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
             currentIndex++;
-            while (currentIndex < length8 && lexeme.charCodeAt(currentIndex) != 0x7d) {
+            while (currentIndex < length8 && lexeme.codeUnitAt(currentIndex) != 0x7D) {
               currentIndex++;
             }
             return currentIndex + 1;
@@ -4358,7 +4358,7 @@
             reportError3(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
             return length8;
           }
-          currentChar = lexeme.charCodeAt(currentIndex);
+          currentChar = lexeme.codeUnitAt(currentIndex);
         }
         if (digitCount < 1 || digitCount > 6) {
           reportError3(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
@@ -4371,9 +4371,9 @@
           return length8;
         }
         int firstDigit = currentChar;
-        int secondDigit = lexeme.charCodeAt(currentIndex + 1);
-        int thirdDigit = lexeme.charCodeAt(currentIndex + 2);
-        int fourthDigit = lexeme.charCodeAt(currentIndex + 3);
+        int secondDigit = lexeme.codeUnitAt(currentIndex + 1);
+        int thirdDigit = lexeme.codeUnitAt(currentIndex + 2);
+        int fourthDigit = lexeme.codeUnitAt(currentIndex + 3);
         if (!isHexDigit(firstDigit) || !isHexDigit(secondDigit) || !isHexDigit(thirdDigit) || !isHexDigit(fourthDigit)) {
           reportError3(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
         } else {
@@ -4393,7 +4393,7 @@
   void validateFormalParameterList(FormalParameterList parameterList) {
     for (FormalParameter parameter in parameterList.parameters) {
       if (parameter is FieldFormalParameter) {
-        reportError(ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, (parameter as FieldFormalParameter).identifier, []);
+        reportError(ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, ((parameter as FieldFormalParameter)).identifier, []);
       }
     }
   }
@@ -4626,9 +4626,9 @@
     }
   }
 }
-class AnalysisErrorListener_1 implements AnalysisErrorListener {
+class AnalysisErrorListener_4 implements AnalysisErrorListener {
   List<bool> errorFound;
-  AnalysisErrorListener_1(this.errorFound);
+  AnalysisErrorListener_4(this.errorFound);
   void onError(AnalysisError error) {
     errorFound[0] = true;
   }
@@ -4755,24 +4755,24 @@
    * @param severity the severity of the error
    * @param message the message template used to create the message to be displayed for the error
    */
-  ParserErrorCode.con1(String ___name, int ___ordinal, ErrorSeverity severity, String message) {
-    _jtd_constructor_208_impl(___name, ___ordinal, severity, message);
+  ParserErrorCode.con1(String ___name, int ___ordinal, ErrorSeverity severity2, String message2) {
+    _jtd_constructor_217_impl(___name, ___ordinal, severity2, message2);
   }
-  _jtd_constructor_208_impl(String ___name, int ___ordinal, ErrorSeverity severity, String message) {
+  _jtd_constructor_217_impl(String ___name, int ___ordinal, ErrorSeverity severity2, String message2) {
     __name = ___name;
     __ordinal = ___ordinal;
-    this._severity = severity;
-    this._message = message;
+    this._severity = severity2;
+    this._message = message2;
   }
   /**
    * Initialize a newly created error code to have the given message and a severity of ERROR.
    * @param message the message template used to create the message to be displayed for the error
    */
   ParserErrorCode.con2(String ___name, int ___ordinal, String message) {
-    _jtd_constructor_209_impl(___name, ___ordinal, message);
+    _jtd_constructor_218_impl(___name, ___ordinal, message);
   }
-  _jtd_constructor_209_impl(String ___name, int ___ordinal, String message) {
-    _jtd_constructor_208_impl(___name, ___ordinal, ErrorSeverity.ERROR, message);
+  _jtd_constructor_218_impl(String ___name, int ___ordinal, String message) {
+    _jtd_constructor_217_impl(___name, ___ordinal, ErrorSeverity.ERROR, message);
   }
   ErrorSeverity get errorSeverity => _severity;
   String get message => _message;
@@ -4942,7 +4942,7 @@
         _writer.print(line);
         nl2();
       }
-      if (token == node.endToken) {
+      if (identical(token, node.endToken)) {
         break;
       }
     }
@@ -4950,12 +4950,12 @@
   }
   Object visitCommentReference(CommentReference node) => null;
   Object visitCompilationUnit(CompilationUnit node) {
-    ScriptTag scriptTag5 = node.scriptTag;
+    ScriptTag scriptTag7 = node.scriptTag;
     NodeList<Directive> directives4 = node.directives;
-    visit(scriptTag5);
-    String prefix = scriptTag5 == null ? "" : " ";
+    visit(scriptTag7);
+    String prefix = scriptTag7 == null ? "" : " ";
     visitList7(prefix, directives4, "\n");
-    prefix = scriptTag5 == null && directives4.isEmpty ? "" : "\n\n";
+    prefix = scriptTag7 == null && directives4.isEmpty ? "" : "\n\n";
     visitList7(prefix, node.declarations, "\n");
     return null;
   }
@@ -5032,7 +5032,7 @@
   }
   Object visitExportDirective(ExportDirective node) {
     _writer.print("export ");
-    visit(node.libraryUri);
+    visit(node.uri);
     visitList7(" ", node.combinators, " ");
     _writer.print(';');
     return null;
@@ -5082,14 +5082,14 @@
     String groupEnd = null;
     _writer.print('(');
     NodeList<FormalParameter> parameters11 = node.parameters;
-    int size6 = parameters11.length;
-    for (int i = 0; i < size6; i++) {
+    int size7 = parameters11.length;
+    for (int i = 0; i < size7; i++) {
       FormalParameter parameter = parameters11[i];
       if (i > 0) {
         _writer.print(", ");
       }
       if (groupEnd == null && parameter is DefaultFormalParameter) {
-        if (parameter.kind == ParameterKind.NAMED) {
+        if (identical(parameter.kind, ParameterKind.NAMED)) {
           groupEnd = "}";
           _writer.print('{');
         } else {
@@ -5179,7 +5179,7 @@
   }
   Object visitImportDirective(ImportDirective node) {
     _writer.print("import ");
-    visit(node.libraryUri);
+    visit(node.uri);
     visit7(" as ", node.prefix);
     visitList7(" ", node.combinators, " ");
     _writer.print(';');
@@ -5324,7 +5324,7 @@
   }
   Object visitPartDirective(PartDirective node) {
     _writer.print("part ");
-    visit(node.partUri);
+    visit(node.uri);
     _writer.print(';');
     return null;
   }
@@ -5366,12 +5366,12 @@
     return null;
   }
   Object visitReturnStatement(ReturnStatement node) {
-    Expression expression15 = node.expression;
-    if (expression15 == null) {
+    Expression expression16 = node.expression;
+    if (expression16 == null) {
       _writer.print("return;");
     } else {
       _writer.print("return ");
-      expression15.accept(this);
+      expression16.accept(this);
       _writer.print(";");
     }
     return null;
@@ -5594,8 +5594,8 @@
    */
   void visitList5(NodeList<ASTNode> nodes, String separator) {
     if (nodes != null) {
-      int size7 = nodes.length;
-      for (int i = 0; i < size7; i++) {
+      int size8 = nodes.length;
+      for (int i = 0; i < size8; i++) {
         if ("\n" == separator) {
           _writer.print("\n");
           indent();
@@ -5614,9 +5614,9 @@
    */
   void visitList6(NodeList<ASTNode> nodes, String separator, String suffix) {
     if (nodes != null) {
-      int size8 = nodes.length;
-      if (size8 > 0) {
-        for (int i = 0; i < size8; i++) {
+      int size9 = nodes.length;
+      if (size9 > 0) {
+        for (int i = 0; i < size9; i++) {
           if (i > 0) {
             _writer.print(separator);
           }
@@ -5634,10 +5634,10 @@
    */
   void visitList7(String prefix, NodeList<ASTNode> nodes, String separator) {
     if (nodes != null) {
-      int size9 = nodes.length;
-      if (size9 > 0) {
+      int size10 = nodes.length;
+      if (size10 > 0) {
         _writer.print(prefix);
-        for (int i = 0; i < size9; i++) {
+        for (int i = 0; i < size10; i++) {
           if (i > 0) {
             _writer.print(separator);
           }
diff --git a/pkg/analyzer-experimental/lib/src/generated/resolver.dart b/pkg/analyzer-experimental/lib/src/generated/resolver.dart
new file mode 100644
index 0000000..ed1a436
--- /dev/null
+++ b/pkg/analyzer-experimental/lib/src/generated/resolver.dart
@@ -0,0 +1,4479 @@
+// This code was auto-generated, is not intended to be edited, and is subject to
+// significant change. Please see the README file for more information.
+
+library engine.resolver;
+
+import 'dart:collection';
+import 'java_core.dart';
+import 'java_engine.dart';
+import 'source.dart';
+import 'error.dart';
+import 'scanner.dart' show Keyword, TokenType, Token, KeywordToken, StringToken;
+import 'utilities_dart.dart';
+import 'ast.dart';
+import 'element.dart' hide HideCombinator, ShowCombinator;
+import 'engine.dart';
+import 'element.dart' as __imp_combi show HideCombinator, ShowCombinator;
+
+/**
+ * Instances of the class {@code CompilationUnitBuilder} build an element model for a single
+ * compilation unit.
+ */
+class CompilationUnitBuilder {
+  /**
+   * The analysis context in which the element model will be built.
+   */
+  AnalysisContextImpl _analysisContext;
+  /**
+   * The listener to which errors will be reported.
+   */
+  AnalysisErrorListener _errorListener;
+  /**
+   * Initialize a newly created compilation unit element builder.
+   * @param analysisContext the analysis context in which the element model will be built
+   * @param errorListener the listener to which errors will be reported
+   */
+  CompilationUnitBuilder(AnalysisContextImpl analysisContext, AnalysisErrorListener errorListener) {
+    this._analysisContext = analysisContext;
+    this._errorListener = errorListener;
+  }
+  /**
+   * Build the compilation unit element for the given source.
+   * @param source the source describing the compilation unit
+   * @return the compilation unit element that was built
+   * @throws AnalysisException if the analysis could not be performed
+   */
+  CompilationUnitElementImpl buildCompilationUnit(Source source) => buildCompilationUnit2(source, _analysisContext.parse2(source, _errorListener));
+  /**
+   * Build the compilation unit element for the given source.
+   * @param source the source describing the compilation unit
+   * @param unit the AST structure representing the compilation unit
+   * @return the compilation unit element that was built
+   * @throws AnalysisException if the analysis could not be performed
+   */
+  CompilationUnitElementImpl buildCompilationUnit2(Source source11, CompilationUnit unit) {
+    ElementHolder holder = new ElementHolder();
+    ElementBuilder builder = new ElementBuilder(holder);
+    unit.accept(builder);
+    CompilationUnitElementImpl element = new CompilationUnitElementImpl(source11.shortName);
+    element.accessors = holder.accessors;
+    element.functions = holder.functions;
+    element.source = source11;
+    element.typeAliases = holder.typeAliases;
+    element.types = holder.types;
+    element.variables = holder.variables;
+    unit.element = element;
+    return element;
+  }
+}
+/**
+ * Instances of the class {@code ElementBuilder} traverse an AST structure and build the element
+ * model representing the AST structure.
+ */
+class ElementBuilder extends RecursiveASTVisitor<Object> {
+  /**
+   * The element holder associated with the element that is currently being built.
+   */
+  ElementHolder _currentHolder;
+  /**
+   * A flag indicating whether a variable declaration is in the context of a field declaration.
+   */
+  bool _inFieldContext = false;
+  /**
+   * Initialize a newly created element builder to build the elements for a compilation unit.
+   * @param initialHolder the element holder associated with the compilation unit being built
+   */
+  ElementBuilder(ElementHolder initialHolder) {
+    _currentHolder = initialHolder;
+  }
+  Object visitCatchClause(CatchClause node) {
+    SimpleIdentifier exceptionParameter2 = node.exceptionParameter;
+    if (exceptionParameter2 != null) {
+      VariableElementImpl exception = new VariableElementImpl.con1(exceptionParameter2);
+      _currentHolder.addVariable(exception);
+      exceptionParameter2.element = exception;
+      SimpleIdentifier stackTraceParameter2 = node.stackTraceParameter;
+      if (stackTraceParameter2 != null) {
+        VariableElementImpl stackTrace = new VariableElementImpl.con1(stackTraceParameter2);
+        _currentHolder.addVariable(stackTrace);
+        stackTraceParameter2.element = stackTrace;
+      }
+    }
+    node.visitChildren(this);
+    return null;
+  }
+  Object visitClassDeclaration(ClassDeclaration node) {
+    ElementHolder holder = new ElementHolder();
+    visitChildren(holder, node);
+    SimpleIdentifier className = node.name;
+    ClassElementImpl element = new ClassElementImpl(className);
+    List<ConstructorElement> constructors3 = holder.constructors;
+    if (constructors3.length == 0) {
+      ConstructorElementImpl constructor = new ConstructorElementImpl(null);
+      constructor.synthetic = true;
+      FunctionTypeImpl type = new FunctionTypeImpl.con1(constructor);
+      type.returnType = element.type;
+      constructor.type = type;
+      constructors3 = <ConstructorElement> [constructor];
+    }
+    element.abstract = node.abstractKeyword != null;
+    element.accessors = holder.accessors;
+    element.constructors = constructors3;
+    element.fields = holder.fields;
+    element.methods = holder.methods;
+    List<TypeVariableElement> typeVariables4 = holder.typeVariables;
+    element.typeVariables = typeVariables4;
+    InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element);
+    int typeVariableCount = typeVariables4.length;
+    List<Type2> typeArguments = new List<Type2>.fixedLength(typeVariableCount);
+    for (int i = 0; i < typeVariableCount; i++) {
+      TypeVariableElementImpl typeVariable = (typeVariables4[i] as TypeVariableElementImpl);
+      TypeVariableTypeImpl typeArgument = new TypeVariableTypeImpl(typeVariable);
+      typeVariable.type = typeArgument;
+      typeArguments[i] = typeArgument;
+    }
+    interfaceType.typeArguments = typeArguments;
+    element.type = interfaceType;
+    _currentHolder.addType(element);
+    className.element = element;
+    return null;
+  }
+  Object visitClassTypeAlias(ClassTypeAlias node) {
+    ElementHolder holder = new ElementHolder();
+    visitChildren(holder, node);
+    SimpleIdentifier className = node.name;
+    ClassElementImpl element = new ClassElementImpl(className);
+    element.abstract = node.abstractKeyword != null;
+    List<TypeVariableElement> typeVariables5 = holder.typeVariables;
+    element.typeVariables = typeVariables5;
+    InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element);
+    int typeVariableCount = typeVariables5.length;
+    List<Type2> typeArguments = new List<Type2>.fixedLength(typeVariableCount);
+    for (int i = 0; i < typeVariableCount; i++) {
+      TypeVariableElementImpl typeVariable = (typeVariables5[i] as TypeVariableElementImpl);
+      TypeVariableTypeImpl typeArgument = new TypeVariableTypeImpl(typeVariable);
+      typeVariable.type = typeArgument;
+      typeArguments[i] = typeArgument;
+    }
+    interfaceType.typeArguments = typeArguments;
+    element.type = interfaceType;
+    _currentHolder.addType(element);
+    className.element = element;
+    return null;
+  }
+  Object visitConstructorDeclaration(ConstructorDeclaration node) {
+    ElementHolder holder = new ElementHolder();
+    visitChildren(holder, node);
+    SimpleIdentifier constructorName = node.name;
+    ConstructorElementImpl element = new ConstructorElementImpl(constructorName);
+    if (node.factoryKeyword != null) {
+      element.factory = true;
+    }
+    element.functions = holder.functions;
+    element.labels = holder.labels;
+    element.localVariables = holder.variables;
+    element.parameters = holder.parameters;
+    _currentHolder.addConstructor(element);
+    node.element = element;
+    if (constructorName != null) {
+      constructorName.element = element;
+    }
+    return null;
+  }
+  Object visitDefaultFormalParameter(DefaultFormalParameter node) {
+    ElementHolder holder = new ElementHolder();
+    visitChildren(holder, node.defaultValue);
+    FunctionElementImpl initializer = new FunctionElementImpl();
+    initializer.functions = holder.functions;
+    initializer.labels = holder.labels;
+    initializer.localVariables = holder.variables;
+    initializer.parameters = holder.parameters;
+    SimpleIdentifier parameterName = node.parameter.identifier;
+    ParameterElementImpl parameter = new ParameterElementImpl(parameterName);
+    parameter.const2 = node.isConst();
+    parameter.final2 = node.isFinal();
+    parameter.initializer = initializer;
+    parameter.parameterKind = node.kind;
+    _currentHolder.addParameter(parameter);
+    parameterName.element = parameter;
+    node.parameter.accept(this);
+    return null;
+  }
+  Object visitFieldDeclaration(FieldDeclaration node) {
+    bool wasInField = _inFieldContext;
+    _inFieldContext = true;
+    try {
+      node.visitChildren(this);
+    } finally {
+      _inFieldContext = wasInField;
+    }
+    return null;
+  }
+  Object visitFieldFormalParameter(FieldFormalParameter node) {
+    if (node.parent is! DefaultFormalParameter) {
+      SimpleIdentifier parameterName = node.identifier;
+      ParameterElementImpl parameter = new ParameterElementImpl(parameterName);
+      parameter.const2 = node.isConst();
+      parameter.initializingFormal = true;
+      parameter.final2 = node.isFinal();
+      parameter.parameterKind = node.kind;
+      _currentHolder.addParameter(parameter);
+      parameterName.element = parameter;
+    }
+    node.visitChildren(this);
+    return null;
+  }
+  Object visitFunctionDeclaration(FunctionDeclaration node) {
+    ElementHolder holder = new ElementHolder();
+    visitChildren(holder, node);
+    SimpleIdentifier functionName = node.name;
+    FunctionElementImpl element = new FunctionElementImpl.con1(functionName);
+    element.functions = holder.functions;
+    element.labels = holder.labels;
+    element.localVariables = holder.variables;
+    element.parameters = holder.parameters;
+    _currentHolder.addFunction(element);
+    functionName.element = element;
+    return null;
+  }
+  Object visitFunctionExpression(FunctionExpression node) {
+    ElementHolder holder = new ElementHolder();
+    visitChildren(holder, node);
+    SimpleIdentifier functionName = null;
+    FunctionElementImpl element = new FunctionElementImpl.con1(functionName);
+    element.functions = holder.functions;
+    element.labels = holder.labels;
+    element.localVariables = holder.variables;
+    element.parameters = holder.parameters;
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(element);
+    element.type = type;
+    _currentHolder.addFunction(element);
+    node.element = element;
+    return null;
+  }
+  Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+    ElementHolder holder = new ElementHolder();
+    visitChildren(holder, node);
+    SimpleIdentifier aliasName = node.name;
+    List<ParameterElement> parameters10 = holder.parameters;
+    TypeAliasElementImpl element = new TypeAliasElementImpl(aliasName);
+    element.parameters = parameters10;
+    element.typeVariables = holder.typeVariables;
+    FunctionTypeImpl type = new FunctionTypeImpl.con2(element);
+    element.type = type;
+    _currentHolder.addTypeAlias(element);
+    aliasName.element = element;
+    return null;
+  }
+  Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    if (node.parent is! DefaultFormalParameter) {
+      SimpleIdentifier parameterName = node.identifier;
+      ParameterElementImpl parameter = new ParameterElementImpl(parameterName);
+      parameter.parameterKind = node.kind;
+      _currentHolder.addParameter(parameter);
+      parameterName.element = parameter;
+    }
+    visitChildren(new ElementHolder(), node);
+    return null;
+  }
+  Object visitLabeledStatement(LabeledStatement node) {
+    bool onSwitchStatement = node.statement is SwitchStatement;
+    for (Label label in node.labels) {
+      SimpleIdentifier labelName = label.label;
+      LabelElementImpl element = new LabelElementImpl(labelName, onSwitchStatement, false);
+      _currentHolder.addLabel(element);
+      labelName.element = element;
+    }
+    node.visitChildren(this);
+    return null;
+  }
+  Object visitMethodDeclaration(MethodDeclaration node) {
+    ElementHolder holder = new ElementHolder();
+    visitChildren(holder, node);
+    Token property = node.propertyKeyword;
+    if (property == null) {
+      Identifier methodName = node.name;
+      String nameOfMethod = methodName.name;
+      if (nameOfMethod == TokenType.MINUS.lexeme && node.parameters.parameters.length == 0) {
+        nameOfMethod = "unary-";
+      }
+      MethodElementImpl element = new MethodElementImpl.con2(nameOfMethod, methodName.offset);
+      Token keyword = node.modifierKeyword;
+      element.abstract = matches(keyword, Keyword.ABSTRACT);
+      element.functions = holder.functions;
+      element.labels = holder.labels;
+      element.localVariables = holder.variables;
+      element.parameters = holder.parameters;
+      element.static = matches(keyword, Keyword.STATIC);
+      _currentHolder.addMethod(element);
+      methodName.element = element;
+    } else {
+      Identifier propertyNameNode = node.name;
+      String propertyName = propertyNameNode.name;
+      FieldElementImpl field = (_currentHolder.getField(propertyName) as FieldElementImpl);
+      if (field == null) {
+        field = new FieldElementImpl.con2(node.name.name);
+        field.final2 = true;
+        field.static = matches(node.modifierKeyword, Keyword.STATIC);
+        _currentHolder.addField(field);
+      }
+      if (matches(property, Keyword.GET)) {
+        PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2(propertyNameNode);
+        getter.functions = holder.functions;
+        getter.labels = holder.labels;
+        getter.localVariables = holder.variables;
+        getter.field = field;
+        getter.getter = true;
+        field.getter = getter;
+        _currentHolder.addAccessor(getter);
+        propertyNameNode.element = getter;
+      } else {
+        PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con2(propertyNameNode);
+        setter.functions = holder.functions;
+        setter.labels = holder.labels;
+        setter.localVariables = holder.variables;
+        setter.parameters = holder.parameters;
+        setter.field = field;
+        setter.setter = true;
+        field.setter = setter;
+        field.final2 = false;
+        _currentHolder.addAccessor(setter);
+        propertyNameNode.element = setter;
+      }
+    }
+    return null;
+  }
+  Object visitSimpleFormalParameter(SimpleFormalParameter node) {
+    if (node.parent is! DefaultFormalParameter) {
+      SimpleIdentifier parameterName = node.identifier;
+      ParameterElementImpl parameter = new ParameterElementImpl(parameterName);
+      parameter.const2 = node.isConst();
+      parameter.final2 = node.isFinal();
+      parameter.parameterKind = node.kind;
+      _currentHolder.addParameter(parameter);
+      parameterName.element = parameter;
+    }
+    node.visitChildren(this);
+    return null;
+  }
+  Object visitSwitchCase(SwitchCase node) {
+    for (Label label in node.labels) {
+      SimpleIdentifier labelName = label.label;
+      LabelElementImpl element = new LabelElementImpl(labelName, false, true);
+      _currentHolder.addLabel(element);
+      labelName.element = element;
+    }
+    node.visitChildren(this);
+    return null;
+  }
+  Object visitSwitchDefault(SwitchDefault node) {
+    for (Label label in node.labels) {
+      SimpleIdentifier labelName = label.label;
+      LabelElementImpl element = new LabelElementImpl(labelName, false, true);
+      _currentHolder.addLabel(element);
+      labelName.element = element;
+    }
+    node.visitChildren(this);
+    return null;
+  }
+  Object visitTypeParameter(TypeParameter node) {
+    SimpleIdentifier parameterName = node.name;
+    TypeVariableElementImpl element = new TypeVariableElementImpl(parameterName);
+    TypeVariableTypeImpl type = new TypeVariableTypeImpl(element);
+    element.type = type;
+    _currentHolder.addTypeVariable(element);
+    parameterName.element = element;
+    node.visitChildren(this);
+    return null;
+  }
+  Object visitVariableDeclaration(VariableDeclaration node) {
+    VariableElementImpl element;
+    if (_inFieldContext) {
+      SimpleIdentifier fieldName = node.name;
+      FieldElementImpl field = new FieldElementImpl.con1(fieldName);
+      element = field;
+      _currentHolder.addField(field);
+      fieldName.element = field;
+    } else {
+      SimpleIdentifier variableName = node.name;
+      element = new VariableElementImpl.con1(variableName);
+      _currentHolder.addVariable(element);
+      variableName.element = element;
+    }
+    Token keyword26 = ((node.parent as VariableDeclarationList)).keyword;
+    bool isFinal = matches(keyword26, Keyword.FINAL);
+    element.const2 = matches(keyword26, Keyword.CONST);
+    element.final2 = isFinal;
+    if (node.initializer != null) {
+      ElementHolder holder = new ElementHolder();
+      bool wasInFieldContext = _inFieldContext;
+      _inFieldContext = false;
+      try {
+        visitChildren(holder, node.initializer);
+      } finally {
+        _inFieldContext = wasInFieldContext;
+      }
+      FunctionElementImpl initializer = new FunctionElementImpl();
+      initializer.functions = holder.functions;
+      initializer.labels = holder.labels;
+      initializer.localVariables = holder.variables;
+      initializer.synthetic = true;
+      element.initializer = initializer;
+    }
+    if (_inFieldContext) {
+      FieldElementImpl field = (element as FieldElementImpl);
+      PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con1(field);
+      getter.getter = true;
+      _currentHolder.addAccessor(getter);
+      field.getter = getter;
+      if (!isFinal) {
+        PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con1(field);
+        setter.setter = true;
+        _currentHolder.addAccessor(setter);
+        field.setter = setter;
+      }
+      field.static = matches(((node.parent.parent as FieldDeclaration)).keyword, Keyword.STATIC);
+    }
+    node.visitChildren(this);
+    return null;
+  }
+  /**
+   * Return {@code true} if the given token is a token for the given keyword.
+   * @param token the token being tested
+   * @param keyword the keyword being tested for
+   * @return {@code true} if the given token is a token for the given keyword
+   */
+  bool matches(Token token, Keyword keyword34) => token != null && identical(token.type, TokenType.KEYWORD) && identical(((token as KeywordToken)).keyword, keyword34);
+  /**
+   * Make the given holder be the current holder while visiting the children of the given node.
+   * @param holder the holder that will gather elements that are built while visiting the children
+   * @param node the node whose children are to be visited
+   */
+  void visitChildren(ElementHolder holder, ASTNode node) {
+    if (node != null) {
+      ElementHolder previousHolder = _currentHolder;
+      _currentHolder = holder;
+      try {
+        node.visitChildren(this);
+      } finally {
+        _currentHolder = previousHolder;
+      }
+    }
+  }
+}
+/**
+ * Instances of the class {@code ElementHolder} hold on to elements created while traversing an AST
+ * structure so that they can be accessed when creating their enclosing element.
+ */
+class ElementHolder {
+  List<PropertyAccessorElement> _accessors = new List<PropertyAccessorElement>();
+  List<ConstructorElement> _constructors = new List<ConstructorElement>();
+  List<FieldElement> _fields = new List<FieldElement>();
+  List<FunctionElement> _functions = new List<FunctionElement>();
+  List<LabelElement> _labels = new List<LabelElement>();
+  List<MethodElement> _methods = new List<MethodElement>();
+  List<TypeAliasElement> _typeAliases = new List<TypeAliasElement>();
+  List<ParameterElement> _parameters = new List<ParameterElement>();
+  List<ClassElement> _types = new List<ClassElement>();
+  List<TypeVariableElement> _typeVariables = new List<TypeVariableElement>();
+  List<VariableElement> _variables = new List<VariableElement>();
+  /**
+   * Initialize a newly created element holder.
+   */
+  ElementHolder() : super() {
+  }
+  void addAccessor(PropertyAccessorElement element) {
+    _accessors.add(element);
+  }
+  void addConstructor(ConstructorElement element) {
+    _constructors.add(element);
+  }
+  void addField(FieldElement element) {
+    _fields.add(element);
+  }
+  void addFunction(FunctionElement element) {
+    _functions.add(element);
+  }
+  void addLabel(LabelElement element) {
+    _labels.add(element);
+  }
+  void addMethod(MethodElement element) {
+    _methods.add(element);
+  }
+  void addParameter(ParameterElement element) {
+    _parameters.add(element);
+  }
+  void addType(ClassElement element) {
+    _types.add(element);
+  }
+  void addTypeAlias(TypeAliasElement element) {
+    _typeAliases.add(element);
+  }
+  void addTypeVariable(TypeVariableElement element) {
+    _typeVariables.add(element);
+  }
+  void addVariable(VariableElement element) {
+    _variables.add(element);
+  }
+  List<PropertyAccessorElement> get accessors => new List.from(_accessors);
+  List<ConstructorElement> get constructors => new List.from(_constructors);
+  FieldElement getField(String fieldName) {
+    for (FieldElement field in _fields) {
+      if (field.name == fieldName) {
+        return field;
+      }
+    }
+    return null;
+  }
+  List<FieldElement> get fields => new List.from(_fields);
+  List<FunctionElement> get functions => new List.from(_functions);
+  List<LabelElement> get labels => new List.from(_labels);
+  List<MethodElement> get methods => new List.from(_methods);
+  List<ParameterElement> get parameters => new List.from(_parameters);
+  List<TypeAliasElement> get typeAliases => new List.from(_typeAliases);
+  List<ClassElement> get types => new List.from(_types);
+  List<TypeVariableElement> get typeVariables => new List.from(_typeVariables);
+  List<VariableElement> get variables => new List.from(_variables);
+}
+/**
+ * Instances of the class {@code ElementResolver} are used by instances of {@link ResolverVisitor}to resolve references within the AST structure to the elements being referenced. The requirements
+ * for the element resolver are:
+ * <ol>
+ * <li>Every {@link SimpleIdentifier} should be resolved to the element to which it refers.
+ * Specifically:
+ * <ul>
+ * <li>An identifier within the declaration of that name should resolve to the element being
+ * declared.</li>
+ * <li>An identifier denoting a prefix should resolve to the element representing the import that
+ * defines the prefix (an {@link ImportElement}).</li>
+ * <li>An identifier denoting a variable should resolve to the element representing the variable (a{@link VariableElement}).</li>
+ * <li>An identifier denoting a parameter should resolve to the element representing the parameter
+ * (a {@link ParameterElement}).</li>
+ * <li>An identifier denoting a field should resolve to the element representing the getter or
+ * setter being invoked (a {@link PropertyAccessorElement}).</li>
+ * <li>An identifier denoting the name of a method or function being invoked should resolve to the
+ * element representing the method or function (a {@link ExecutableElement}).</li>
+ * <li>An identifier denoting a label should resolve to the element representing the label (a{@link LabelElement}).</li>
+ * </ul>
+ * The identifiers within directives are exceptions to this rule and are covered below.</li>
+ * <li>Every node containing a token representing an operator that can be overridden ({@link BinaryExpression}, {@link PrefixExpression}, {@link PostfixExpression}) should resolve to
+ * the element representing the method invoked by that operator (a {@link MethodElement}).</li>
+ * <li>Every {@link FunctionExpressionInvocation} should resolve to the element representing the
+ * function being invoked (a {@link FunctionElement}). This will be the same element as that to
+ * which the name is resolved if the function has a name, but is provided for those cases where an
+ * unnamed function is being invoked.</li>
+ * <li>Every {@link LibraryDirective} and {@link PartOfDirective} should resolve to the element
+ * representing the library being specified by the directive (a {@link LibraryElement}) unless, in
+ * the case of a part-of directive, the specified library does not exist.</li>
+ * <li>Every {@link ImportDirective} and {@link ExportDirective} should resolve to the element
+ * representing the library being specified by the directive unless the specified library does not
+ * exist (a {@link LibraryElement}).</li>
+ * <li>The identifier representing the prefix in an {@link ImportDirective} should resolve to the
+ * element representing the prefix (a {@link PrefixElement}).</li>
+ * <li>The identifiers in the hide and show combinators in {@link ImportDirective}s and{@link ExportDirective}s should resolve to the elements that are being hidden or shown,
+ * respectively, unless those names are not defined in the specified library (or the specified
+ * library does not exist).</li>
+ * <li>Every {@link PartDirective} should resolve to the element representing the compilation unit
+ * being specified by the string unless the specified compilation unit does not exist (a{@link CompilationUnitElement}).</li>
+ * </ol>
+ * Note that AST nodes that would represent elements that are not defined are not resolved to
+ * anything. This includes such things as references to undeclared variables (which is an error) and
+ * names in hide and show combinators that are not defined in the imported library (which is not an
+ * error).
+ */
+class ElementResolver extends SimpleASTVisitor<Object> {
+  /**
+   * The resolver driving this participant.
+   */
+  ResolverVisitor _resolver;
+  /**
+   * Initialize a newly created visitor to resolve the nodes in a compilation unit.
+   * @param resolver the resolver driving this participant
+   */
+  ElementResolver(ResolverVisitor resolver) {
+    this._resolver = resolver;
+  }
+  Object visitAssignmentExpression(AssignmentExpression node) {
+    TokenType operator7 = node.operator.type;
+    if (operator7 != TokenType.EQ) {
+      operator7 = operatorFromCompoundAssignment(operator7);
+      Expression leftNode = node.leftHandSide;
+      if (leftNode != null) {
+        Type2 leftType = leftNode.staticType;
+        if (leftType != null) {
+          Element leftElement = leftType.element;
+          if (leftElement != null) {
+            MethodElement method = lookUpMethod(leftElement, operator7.lexeme, 1, []);
+            if (method != null) {
+              node.element = method;
+            } else {
+            }
+          }
+        }
+      }
+    }
+    return null;
+  }
+  Object visitBinaryExpression(BinaryExpression node) {
+    Token operator8 = node.operator;
+    if (operator8.isUserDefinableOperator()) {
+      Type2 leftType = getType(node.leftOperand);
+      Element leftTypeElement;
+      if (leftType == null) {
+        return null;
+      } else if (leftType is FunctionType) {
+        leftTypeElement = _resolver.typeProvider.functionType.element;
+      } else {
+        leftTypeElement = leftType.element;
+      }
+      String methodName = operator8.lexeme;
+      MethodElement member = lookUpMethod(leftTypeElement, methodName, 1, []);
+      if (member == null) {
+        _resolver.reportError2(ResolverErrorCode.CANNOT_BE_RESOLVED, operator8, [methodName]);
+      } else {
+        node.element = member;
+      }
+    }
+    return null;
+  }
+  Object visitBreakStatement(BreakStatement node) {
+    SimpleIdentifier labelNode = node.label;
+    LabelElementImpl labelElement = lookupLabel(node, labelNode);
+    if (labelElement != null && labelElement.isOnSwitchMember()) {
+      _resolver.reportError(ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, labelNode, []);
+    }
+    return null;
+  }
+  Object visitConstructorName(ConstructorName node) {
+    Type2 type10 = node.type.type;
+    if (type10 is! InterfaceType) {
+      return null;
+    }
+    ClassElement classElement = ((type10 as InterfaceType)).element;
+    ConstructorElement constructor;
+    SimpleIdentifier name14 = node.name;
+    if (name14 == null) {
+      constructor = classElement.unnamedConstructor;
+    } else {
+      constructor = classElement.getNamedConstructor(name14.name);
+      name14.element = constructor;
+    }
+    node.element = constructor;
+    return null;
+  }
+  Object visitContinueStatement(ContinueStatement node) {
+    SimpleIdentifier labelNode = node.label;
+    LabelElementImpl labelElement = lookupLabel(node, labelNode);
+    if (labelElement != null && labelElement.isOnSwitchStatement()) {
+      _resolver.reportError(ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH, labelNode, []);
+    }
+    return null;
+  }
+  Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) => null;
+  Object visitImportDirective(ImportDirective node) {
+    SimpleIdentifier prefixNode = node.prefix;
+    if (prefixNode != null) {
+      String prefixName = prefixNode.name;
+      for (PrefixElement prefixElement in _resolver.definingLibrary.prefixes) {
+        if (prefixElement.name == prefixName) {
+          recordResolution(prefixNode, prefixElement);
+        }
+        return null;
+      }
+    }
+    return null;
+  }
+  Object visitIndexExpression(IndexExpression node) {
+    Type2 arrayType = getType(node.array);
+    if (arrayType == null) {
+      return null;
+    }
+    Element arrayTypeElement = arrayType.element;
+    String operator;
+    if (node.inSetterContext()) {
+      operator = TokenType.INDEX_EQ.lexeme;
+    } else {
+      operator = TokenType.INDEX.lexeme;
+    }
+    MethodElement member = lookUpMethod(arrayTypeElement, operator, 1, []);
+    if (member == null) {
+      _resolver.reportError(ResolverErrorCode.CANNOT_BE_RESOLVED, node, [operator]);
+    } else {
+      node.element = member;
+    }
+    return null;
+  }
+  Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+    node.element = node.constructorName.element;
+    return null;
+  }
+  Object visitLibraryIdentifier(LibraryIdentifier node) => null;
+  Object visitMethodInvocation(MethodInvocation node) {
+    SimpleIdentifier methodName2 = node.methodName;
+    Expression target4 = node.target;
+    Element element;
+    if (target4 == null) {
+      element = _resolver.nameScope.lookup(methodName2, _resolver.definingLibrary);
+      if (element == null) {
+        element = lookUpMethod(_resolver.enclosingClass, methodName2.name, -1, []);
+      }
+    } else {
+      Type2 targetType = getType(target4);
+      if (targetType is InterfaceType) {
+        int parameterCount = 0;
+        List<String> parameterNames = new List<String>();
+        ArgumentList argumentList10 = node.argumentList;
+        for (Expression argument in argumentList10.arguments) {
+          if (argument is NamedExpression) {
+            parameterNames.add(((argument as NamedExpression)).name.label.name);
+          } else {
+            parameterCount++;
+          }
+        }
+        element = lookUpMethod(targetType.element, methodName2.name, parameterCount, new List.from(parameterNames));
+      } else if (target4 is SimpleIdentifier) {
+        Element targetElement = ((target4 as SimpleIdentifier)).element;
+        if (targetElement is PrefixElement) {
+          String name9 = "${((target4 as SimpleIdentifier)).name}.${methodName2}";
+          Identifier functionName = new Identifier_2(name9);
+          element = _resolver.nameScope.lookup(functionName, _resolver.definingLibrary);
+        } else {
+          return null;
+        }
+      } else {
+        return null;
+      }
+    }
+    ExecutableElement invokedMethod = null;
+    if (element is ExecutableElement) {
+      invokedMethod = (element as ExecutableElement);
+    } else if (element is FieldElement) {
+    } else {
+      return null;
+    }
+    if (invokedMethod == null) {
+      return null;
+    }
+    recordResolution(methodName2, invokedMethod);
+    return null;
+  }
+  Object visitPostfixExpression(PostfixExpression node) {
+    Token operator9 = node.operator;
+    if (operator9.isUserDefinableOperator()) {
+      Type2 operandType = getType(node.operand);
+      if (operandType == null) {
+        return null;
+      }
+      Element operandTypeElement = operandType.element;
+      String methodName;
+      if (identical(operator9.type, TokenType.PLUS_PLUS)) {
+        methodName = TokenType.PLUS.lexeme;
+      } else {
+        methodName = TokenType.MINUS.lexeme;
+      }
+      MethodElement member = lookUpMethod(operandTypeElement, methodName, 1, []);
+      if (member == null) {
+        _resolver.reportError2(ResolverErrorCode.CANNOT_BE_RESOLVED, operator9, [methodName]);
+      } else {
+        node.element = member;
+      }
+    }
+    return null;
+  }
+  Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+    SimpleIdentifier prefix5 = node.prefix;
+    SimpleIdentifier identifier10 = node.identifier;
+    Element prefixElement = prefix5.element;
+    if (prefixElement is PrefixElement) {
+      Element element = _resolver.nameScope.lookup(node, _resolver.definingLibrary);
+      if (element == null) {
+        return null;
+      }
+      recordResolution(identifier10, element);
+      recordResolution(node, element);
+      return null;
+    }
+    if (prefixElement is ClassElement) {
+      Element memberElement;
+      if (node.identifier.inSetterContext()) {
+        memberElement = lookUpSetterInType((prefixElement as ClassElement), identifier10.name);
+      } else {
+        memberElement = lookUpGetterInType((prefixElement as ClassElement), identifier10.name);
+      }
+      if (memberElement == null) {
+        MethodElement methodElement = lookUpMethod(prefixElement, identifier10.name, -1, []);
+        if (methodElement != null) {
+          recordResolution(identifier10, methodElement);
+          recordResolution(node, methodElement);
+          return null;
+        }
+      }
+      if (memberElement == null) {
+        _resolver.reportError(ResolverErrorCode.CANNOT_BE_RESOLVED, identifier10, [identifier10.name]);
+      } else {
+        recordResolution(identifier10, memberElement);
+        recordResolution(node, memberElement);
+      }
+      return null;
+    }
+    Element variableType;
+    if (prefixElement is PropertyAccessorElement) {
+      PropertyAccessorElement accessor = (prefixElement as PropertyAccessorElement);
+      if (accessor.isGetter()) {
+        variableType = accessor.type.returnType.element;
+      } else {
+        variableType = accessor.type.normalParameterTypes[0].element;
+      }
+    } else if (prefixElement is VariableElement) {
+      variableType = ((prefixElement as VariableElement)).type.element;
+    } else {
+      return null;
+    }
+    PropertyAccessorElement memberElement;
+    if (node.identifier.inGetterContext()) {
+      memberElement = lookUpGetter(variableType, identifier10.name);
+    } else {
+      memberElement = lookUpSetter(variableType, identifier10.name);
+    }
+    if (memberElement == null) {
+      MethodElement methodElement = lookUpMethod(variableType, identifier10.name, -1, []);
+      if (methodElement != null) {
+        recordResolution(identifier10, methodElement);
+        recordResolution(node, methodElement);
+        return null;
+      }
+    }
+    if (memberElement == null) {
+      _resolver.reportError(ResolverErrorCode.CANNOT_BE_RESOLVED, identifier10, [identifier10.name]);
+    } else {
+      recordResolution(identifier10, memberElement);
+      recordResolution(node, memberElement);
+    }
+    return null;
+  }
+  Object visitPrefixExpression(PrefixExpression node) {
+    Token operator10 = node.operator;
+    TokenType operatorType = operator10.type;
+    if (operatorType.isUserDefinableOperator() || identical(operatorType, TokenType.PLUS_PLUS) || identical(operatorType, TokenType.MINUS_MINUS)) {
+      Type2 operandType = getType(node.operand);
+      if (operandType == null) {
+        return null;
+      }
+      Element operandTypeElement = operandType.element;
+      String methodName;
+      if (identical(operatorType, TokenType.PLUS_PLUS)) {
+        methodName = TokenType.PLUS.lexeme;
+      } else if (identical(operatorType, TokenType.MINUS_MINUS)) {
+        methodName = TokenType.MINUS.lexeme;
+      } else if (identical(operatorType, TokenType.MINUS)) {
+        methodName = "unary-";
+      } else {
+        methodName = operator10.lexeme;
+      }
+      MethodElement member = lookUpMethod(operandTypeElement, methodName, 1, []);
+      if (member == null) {
+        _resolver.reportError2(ResolverErrorCode.CANNOT_BE_RESOLVED, operator10, [methodName]);
+      } else {
+        node.element = member;
+      }
+    }
+    return null;
+  }
+  Object visitPropertyAccess(PropertyAccess node) {
+    Type2 targetType = getType(node.realTarget);
+    if (targetType is! InterfaceType) {
+      return null;
+    }
+    ClassElement targetElement = ((targetType as InterfaceType)).element;
+    SimpleIdentifier identifier = node.propertyName;
+    PropertyAccessorElement memberElement;
+    if (identifier.inSetterContext()) {
+      memberElement = lookUpSetter(targetElement, identifier.name);
+    } else {
+      memberElement = lookUpGetter(targetElement, identifier.name);
+    }
+    if (memberElement == null) {
+      MethodElement methodElement = lookUpMethod(targetElement, identifier.name, -1, []);
+      if (methodElement != null) {
+        recordResolution(identifier, methodElement);
+        return null;
+      }
+    }
+    if (memberElement == null) {
+      _resolver.reportError(ResolverErrorCode.CANNOT_BE_RESOLVED, identifier, [identifier.name]);
+    } else {
+      recordResolution(identifier, memberElement);
+    }
+    return null;
+  }
+  Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
+    ClassElement enclosingClass2 = _resolver.enclosingClass;
+    if (enclosingClass2 == null) {
+      return null;
+    }
+    SimpleIdentifier name = node.constructorName;
+    ConstructorElement element;
+    if (name == null) {
+      element = enclosingClass2.unnamedConstructor;
+    } else {
+      element = enclosingClass2.getNamedConstructor(name.name);
+    }
+    if (element == null) {
+      return null;
+    }
+    if (name != null) {
+      recordResolution(name, element);
+    }
+    node.element = element;
+    return null;
+  }
+  Object visitSimpleIdentifier(SimpleIdentifier node) {
+    if (node.element != null) {
+      return null;
+    }
+    Element element = _resolver.nameScope.lookup(node, _resolver.definingLibrary);
+    if (element == null) {
+      if (node.inGetterContext()) {
+        element = lookUpGetter(_resolver.enclosingClass, node.name);
+      } else {
+        element = lookUpSetter(_resolver.enclosingClass, node.name);
+      }
+    }
+    if (element == null) {
+      element = lookUpMethod(_resolver.enclosingClass, node.name, -1, []);
+    }
+    if (element == null) {
+    }
+    recordResolution(node, element);
+    return null;
+  }
+  Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    ClassElement enclosingClass3 = _resolver.enclosingClass;
+    if (enclosingClass3 == null) {
+      return null;
+    }
+    ClassElement superclass = getSuperclass(enclosingClass3);
+    if (superclass == null) {
+      return null;
+    }
+    SimpleIdentifier name = node.constructorName;
+    ConstructorElement element;
+    if (name == null) {
+      element = superclass.unnamedConstructor;
+    } else {
+      element = superclass.getNamedConstructor(name.name);
+    }
+    if (element == null) {
+      return null;
+    }
+    if (name != null) {
+      recordResolution(name, element);
+    }
+    node.element = element;
+    return null;
+  }
+  /**
+   * Return the element representing the superclass of the given class.
+   * @param targetClass the class whose superclass is to be returned
+   * @return the element representing the superclass of the given class
+   */
+  ClassElement getSuperclass(ClassElement targetClass) {
+    InterfaceType superType = targetClass.supertype;
+    if (superType == null) {
+      return null;
+    }
+    return superType.element;
+  }
+  /**
+   * Return the type of the given expression that is to be used for type analysis.
+   * @param expression the expression whose type is to be returned
+   * @return the type of the given expression
+   */
+  Type2 getType(Expression expression) => expression.staticType;
+  /**
+   * Look up the getter with the given name in the given type. Return the element representing the
+   * getter that was found, or {@code null} if there is no getter with the given name.
+   * @param element the element representing the type in which the getter is defined
+   * @param getterName the name of the getter being looked up
+   * @return the element representing the getter that was found
+   */
+  PropertyAccessorElement lookUpGetter(Element element, String getterName) {
+    if (identical(element, DynamicTypeImpl.instance)) {
+      return null;
+    }
+    element = resolveTypeVariable(element);
+    if (element is ClassElement) {
+      ClassElement classElement = (element as ClassElement);
+      PropertyAccessorElement member = classElement.lookUpGetter(getterName, _resolver.definingLibrary);
+      if (member != null) {
+        return member;
+      }
+      return lookUpGetterInInterfaces((element as ClassElement), getterName, new Set<ClassElement>());
+    }
+    return null;
+  }
+  /**
+   * Look up the name of a getter in the interfaces implemented by the given type, either directly
+   * or indirectly. Return the element representing the getter that was found, or {@code null} if
+   * there is no getter with the given name.
+   * @param element the element representing the type in which the getter is defined
+   * @param memberName the name of the getter being looked up
+   * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
+   * to prevent infinite recursion and to optimize the search
+   * @return the element representing the getter that was found
+   */
+  PropertyAccessorElement lookUpGetterInInterfaces(ClassElement targetClass, String memberName, Set<ClassElement> visitedInterfaces) {
+    if (visitedInterfaces.contains(targetClass)) {
+      return null;
+    }
+    javaSetAdd(visitedInterfaces, targetClass);
+    PropertyAccessorElement member = lookUpGetterInType(targetClass, memberName);
+    if (member != null) {
+      return member;
+    }
+    for (InterfaceType interfaceType in targetClass.interfaces) {
+      member = lookUpGetterInInterfaces(interfaceType.element, memberName, visitedInterfaces);
+      if (member != null) {
+        return member;
+      }
+    }
+    ClassElement superclass = getSuperclass(targetClass);
+    if (superclass == null) {
+      return null;
+    }
+    return lookUpGetterInInterfaces(superclass, memberName, visitedInterfaces);
+  }
+  /**
+   * Look up the name of a getter in the given type. Return the element representing the getter that
+   * was found, or {@code null} if there is no getter with the given name.
+   * @param element the element representing the type in which the getter is defined
+   * @param memberName the name of the getter being looked up
+   * @return the element representing the getter that was found
+   */
+  PropertyAccessorElement lookUpGetterInType(ClassElement element, String memberName) {
+    for (PropertyAccessorElement accessor in element.accessors) {
+      if (accessor.isGetter() && accessor.name == memberName) {
+        return accessor;
+      }
+    }
+    return null;
+  }
+  /**
+   * Find the element corresponding to the given label node in the current label scope.
+   * @param parentNode the node containing the given label
+   * @param labelNode the node representing the label being looked up
+   * @return the element corresponding to the given label node in the current scope
+   */
+  LabelElementImpl lookupLabel(ASTNode parentNode, SimpleIdentifier labelNode) {
+    LabelScope labelScope2 = _resolver.labelScope;
+    LabelElementImpl labelElement = null;
+    if (labelNode == null) {
+      if (labelScope2 == null) {
+      } else {
+        labelElement = (labelScope2.lookup2(LabelScope.EMPTY_LABEL) as LabelElementImpl);
+        if (labelElement == null) {
+        }
+      }
+    } else {
+      if (labelScope2 == null) {
+        _resolver.reportError(ResolverErrorCode.UNDEFINED_LABEL, labelNode, [labelNode.name]);
+      } else {
+        labelElement = (labelScope2.lookup(labelNode) as LabelElementImpl);
+        if (labelElement == null) {
+          _resolver.reportError(ResolverErrorCode.UNDEFINED_LABEL, labelNode, [labelNode.name]);
+        } else {
+          recordResolution(labelNode, labelElement);
+        }
+      }
+    }
+    if (labelElement != null) {
+      ExecutableElement labelContainer = labelElement.getAncestor(ExecutableElement);
+      if (labelContainer != _resolver.enclosingFunction) {
+        if (labelNode == null) {
+          _resolver.reportError(ResolverErrorCode.LABEL_IN_OUTER_SCOPE, parentNode, [""]);
+        } else {
+          _resolver.reportError(ResolverErrorCode.LABEL_IN_OUTER_SCOPE, labelNode, [labelNode.name]);
+        }
+        labelElement = null;
+      }
+    }
+    return labelElement;
+  }
+  /**
+   * Look up the method with the given name in the given type. Return the element representing the
+   * method that was found, or {@code null} if there is no method with the given name.
+   * @param element the element representing the type in which the method is defined
+   * @param methodName the name of the method being looked up
+   * @return the element representing the method that was found
+   */
+  MethodElement lookUpMethod(Element element, String methodName, int parameterCount, List<String> parameterNames) {
+    if (identical(element, DynamicTypeImpl.instance)) {
+      return null;
+    }
+    element = resolveTypeVariable(element);
+    if (element is ClassElement) {
+      ClassElement classElement = (element as ClassElement);
+      MethodElement member = classElement.lookUpMethod(methodName, _resolver.definingLibrary);
+      if (member != null) {
+        return member;
+      }
+      return lookUpMethodInInterfaces((element as ClassElement), methodName, new Set<ClassElement>());
+    }
+    return null;
+  }
+  /**
+   * Look up the name of a member in the interfaces implemented by the given type, either directly
+   * or indirectly. Return the element representing the member that was found, or {@code null} if
+   * there is no member with the given name.
+   * @param element the element representing the type in which the member is defined
+   * @param memberName the name of the member being looked up
+   * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
+   * to prevent infinite recursion and to optimize the search
+   * @return the element representing the member that was found
+   */
+  MethodElement lookUpMethodInInterfaces(ClassElement targetClass, String memberName, Set<ClassElement> visitedInterfaces) {
+    if (visitedInterfaces.contains(targetClass)) {
+      return null;
+    }
+    javaSetAdd(visitedInterfaces, targetClass);
+    MethodElement member = lookUpMethodInType(targetClass, memberName);
+    if (member != null) {
+      return member;
+    }
+    for (InterfaceType interfaceType in targetClass.interfaces) {
+      member = lookUpMethodInInterfaces(interfaceType.element, memberName, visitedInterfaces);
+      if (member != null) {
+        return member;
+      }
+    }
+    ClassElement superclass = getSuperclass(targetClass);
+    if (superclass == null) {
+      return null;
+    }
+    return lookUpMethodInInterfaces(superclass, memberName, visitedInterfaces);
+  }
+  /**
+   * Look up the name of a method in the given type. Return the element representing the method that
+   * was found, or {@code null} if there is no method with the given name.
+   * @param element the element representing the type in which the method is defined
+   * @param memberName the name of the method being looked up
+   * @return the element representing the method that was found
+   */
+  MethodElement lookUpMethodInType(ClassElement element, String memberName) {
+    for (MethodElement method in element.methods) {
+      if (method.name == memberName) {
+        return method;
+      }
+    }
+    return null;
+  }
+  /**
+   * Look up the setter with the given name in the given type. Return the element representing the
+   * setter that was found, or {@code null} if there is no setter with the given name.
+   * @param element the element representing the type in which the setter is defined
+   * @param setterName the name of the setter being looked up
+   * @return the element representing the setter that was found
+   */
+  PropertyAccessorElement lookUpSetter(Element element, String setterName) {
+    if (identical(element, DynamicTypeImpl.instance)) {
+      return null;
+    }
+    element = resolveTypeVariable(element);
+    if (element is ClassElement) {
+      ClassElement classElement = (element as ClassElement);
+      PropertyAccessorElement member = classElement.lookUpSetter(setterName, _resolver.definingLibrary);
+      if (member != null) {
+        return member;
+      }
+      return lookUpSetterInInterfaces((element as ClassElement), setterName, new Set<ClassElement>());
+    }
+    return null;
+  }
+  /**
+   * Look up the name of a setter in the interfaces implemented by the given type, either directly
+   * or indirectly. Return the element representing the setter that was found, or {@code null} if
+   * there is no setter with the given name.
+   * @param element the element representing the type in which the setter is defined
+   * @param memberName the name of the setter being looked up
+   * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
+   * to prevent infinite recursion and to optimize the search
+   * @return the element representing the setter that was found
+   */
+  PropertyAccessorElement lookUpSetterInInterfaces(ClassElement targetClass, String memberName, Set<ClassElement> visitedInterfaces) {
+    if (visitedInterfaces.contains(targetClass)) {
+      return null;
+    }
+    javaSetAdd(visitedInterfaces, targetClass);
+    PropertyAccessorElement member = lookUpSetterInType(targetClass, memberName);
+    if (member != null) {
+      return member;
+    }
+    for (InterfaceType interfaceType in targetClass.interfaces) {
+      member = lookUpSetterInInterfaces(interfaceType.element, memberName, visitedInterfaces);
+      if (member != null) {
+        return member;
+      }
+    }
+    ClassElement superclass = getSuperclass(targetClass);
+    if (superclass == null) {
+      return null;
+    }
+    return lookUpSetterInInterfaces(superclass, memberName, visitedInterfaces);
+  }
+  /**
+   * Look up the name of a setter in the given type. Return the element representing the setter that
+   * was found, or {@code null} if there is no setter with the given name.
+   * @param element the element representing the type in which the setter is defined
+   * @param memberName the name of the setter being looked up
+   * @return the element representing the setter that was found
+   */
+  PropertyAccessorElement lookUpSetterInType(ClassElement element, String memberName) {
+    for (PropertyAccessorElement accessor in element.accessors) {
+      if (accessor.isSetter() && accessor.name == memberName) {
+        return accessor;
+      }
+    }
+    return null;
+  }
+  /**
+   * Return the binary operator that is invoked by the given compound assignment operator.
+   * @param operator the assignment operator being mapped
+   * @return the binary operator that invoked by the given assignment operator
+   */
+  TokenType operatorFromCompoundAssignment(TokenType operator) {
+    if (operator == TokenType.AMPERSAND_EQ) {
+      return TokenType.AMPERSAND;
+    } else if (operator == TokenType.BAR_EQ) {
+      return TokenType.BAR;
+    } else if (operator == TokenType.CARET_EQ) {
+      return TokenType.CARET;
+    } else if (operator == TokenType.GT_GT_EQ) {
+      return TokenType.GT_GT;
+    } else if (operator == TokenType.LT_LT_EQ) {
+      return TokenType.LT_LT;
+    } else if (operator == TokenType.MINUS_EQ) {
+      return TokenType.MINUS;
+    } else if (operator == TokenType.PERCENT_EQ) {
+      return TokenType.PERCENT;
+    } else if (operator == TokenType.PLUS_EQ) {
+      return TokenType.PLUS;
+    } else if (operator == TokenType.SLASH_EQ) {
+      return TokenType.SLASH;
+    } else if (operator == TokenType.STAR_EQ) {
+      return TokenType.STAR;
+    } else if (operator == TokenType.TILDE_SLASH_EQ) {
+      return TokenType.TILDE_SLASH;
+    }
+    AnalysisEngine.instance.logger.logError("Failed to map ${operator.lexeme} to it's corresponding operator");
+    return operator;
+  }
+  /**
+   * Record the fact that the given AST node was resolved to the given element.
+   * @param node the AST node that was resolved
+   * @param element the element to which the AST node was resolved
+   */
+  void recordResolution(Identifier node, Element element39) {
+    if (element39 != null) {
+      node.element = element39;
+    }
+  }
+  /**
+   * If the given element is a type variable, resolve it to the class that should be used when
+   * looking up members. Otherwise, return the original element.
+   * @param element the element that is to be resolved if it is a type variable
+   * @return the class that should be used in place of the argument if it is a type variable, or the
+   * original argument if it isn't a type variable
+   */
+  Element resolveTypeVariable(Element element40) {
+    if (element40 is TypeVariableElement) {
+      Type2 bound3 = ((element40 as TypeVariableElement)).bound;
+      if (bound3 == null) {
+        return _resolver.typeProvider.objectType.element;
+      }
+      return bound3.element;
+    }
+    return element40;
+  }
+}
+class Identifier_2 extends Identifier {
+  String name9;
+  Identifier_2(this.name9) : super();
+  accept(ASTVisitor visitor) => null;
+  Token get beginToken => null;
+  Token get endToken => null;
+  String get name => name9;
+  void visitChildren(ASTVisitor<Object> visitor) {
+  }
+}
+/**
+ * Instances of the class {@code Library} represent the data about a single library during the
+ * resolution of some (possibly different) library. They are not intended to be used except during
+ * the resolution process.
+ */
+class Library {
+  /**
+   * The analysis context in which this library is being analyzed.
+   */
+  AnalysisContextImpl _analysisContext;
+  /**
+   * The listener to which analysis errors will be reported.
+   */
+  AnalysisErrorListener _errorListener;
+  /**
+   * The source specifying the defining compilation unit of this library.
+   */
+  Source _librarySource;
+  /**
+   * The library element representing this library.
+   */
+  LibraryElementImpl _libraryElement;
+  /**
+   * A list containing all of the libraries that are imported into this library.
+   */
+  Map<ImportDirective, Library> _importedLibraries = new Map<ImportDirective, Library>();
+  /**
+   * A flag indicating whether this library explicitly imports core.
+   */
+  bool _explicitlyImportsCore = false;
+  /**
+   * A list containing all of the libraries that are exported from this library.
+   */
+  Map<ExportDirective, Library> _exportedLibraries = new Map<ExportDirective, Library>();
+  /**
+   * A table mapping the sources for the compilation units in this library to their corresponding
+   * AST structures.
+   */
+  Map<Source, CompilationUnit> _astMap = new Map<Source, CompilationUnit>();
+  /**
+   * The library scope used when resolving elements within this library's compilation units.
+   */
+  LibraryScope _libraryScope;
+  /**
+   * Initialize a newly created data holder that can maintain the data associated with a library.
+   * @param analysisContext the analysis context in which this library is being analyzed
+   * @param errorListener the listener to which analysis errors will be reported
+   * @param librarySource the source specifying the defining compilation unit of this library
+   */
+  Library(AnalysisContextImpl analysisContext, AnalysisErrorListener errorListener, Source librarySource) {
+    this._analysisContext = analysisContext;
+    this._errorListener = errorListener;
+    this._librarySource = librarySource;
+    this._libraryElement = (analysisContext.getLibraryElementOrNull(librarySource) as LibraryElementImpl);
+  }
+  /**
+   * Record that the given library is exported from this library.
+   * @param importLibrary the library that is exported from this library
+   */
+  void addExport(ExportDirective directive, Library exportLibrary) {
+    _exportedLibraries[directive] = exportLibrary;
+  }
+  /**
+   * Record that the given library is imported into this library.
+   * @param importLibrary the library that is imported into this library
+   */
+  void addImport(ImportDirective directive, Library importLibrary) {
+    _importedLibraries[directive] = importLibrary;
+  }
+  /**
+   * Return the AST structure associated with the given source.
+   * @param source the source representing the compilation unit whose AST is to be returned
+   * @return the AST structure associated with the given source
+   * @throws AnalysisException if an AST structure could not be created for the compilation unit
+   */
+  CompilationUnit getAST(Source source) {
+    CompilationUnit unit = _astMap[source];
+    if (unit == null) {
+      unit = _analysisContext.parse2(source, _errorListener);
+      _astMap[source] = unit;
+    }
+    return unit;
+  }
+  /**
+   * Return a collection containing the sources for the compilation units in this library.
+   * @return the sources for the compilation units in this library
+   */
+  Set<Source> get compilationUnitSources => _astMap.keys.toSet();
+  /**
+   * Return the AST structure associated with the defining compilation unit for this library.
+   * @return the AST structure associated with the defining compilation unit for this library
+   * @throws AnalysisException if an AST structure could not be created for the defining compilation
+   * unit
+   */
+  CompilationUnit get definingCompilationUnit => getAST(librarySource);
+  /**
+   * Return {@code true} if this library explicitly imports core.
+   * @return {@code true} if this library explicitly imports core
+   */
+  bool get explicitlyImportsCore => _explicitlyImportsCore;
+  /**
+   * Return the library exported by the given directive.
+   * @param directive the directive that exports the library to be returned
+   * @return the library exported by the given directive
+   */
+  Library getExport(ExportDirective directive) => _exportedLibraries[directive];
+  /**
+   * Return an array containing the libraries that are exported from this library.
+   * @return an array containing the libraries that are exported from this library
+   */
+  List<Library> get exports {
+    Set<Library> libraries = new Set<Library>();
+    libraries.addAll(_exportedLibraries.values);
+    return new List.from(libraries);
+  }
+  /**
+   * Return the library imported by the given directive.
+   * @param directive the directive that imports the library to be returned
+   * @return the library imported by the given directive
+   */
+  Library getImport(ImportDirective directive) => _importedLibraries[directive];
+  /**
+   * Return an array containing the libraries that are imported into this library.
+   * @return an array containing the libraries that are imported into this library
+   */
+  List<Library> get imports {
+    Set<Library> libraries = new Set<Library>();
+    libraries.addAll(_importedLibraries.values);
+    return new List.from(libraries);
+  }
+  /**
+   * Return an array containing the libraries that are either imported or exported from this
+   * library.
+   * @return the libraries that are either imported or exported from this library
+   */
+  List<Library> get importsAndExports {
+    Set<Library> libraries = new Set<Library>();
+    libraries.addAll(_importedLibraries.values);
+    libraries.addAll(_exportedLibraries.values);
+    return new List.from(libraries);
+  }
+  /**
+   * Return the library element representing this library, creating it if necessary.
+   * @return the library element representing this library
+   */
+  LibraryElementImpl get libraryElement {
+    if (_libraryElement == null) {
+      _libraryElement = (_analysisContext.getLibraryElement(_librarySource) as LibraryElementImpl);
+    }
+    return _libraryElement;
+  }
+  /**
+   * Return the library scope used when resolving elements within this library's compilation units.
+   * @return the library scope used when resolving elements within this library's compilation units
+   */
+  LibraryScope get libraryScope {
+    if (_libraryScope == null) {
+      _libraryScope = new LibraryScope(_libraryElement, _errorListener);
+    }
+    return _libraryScope;
+  }
+  /**
+   * Return the source specifying the defining compilation unit of this library.
+   * @return the source specifying the defining compilation unit of this library
+   */
+  Source get librarySource => _librarySource;
+  /**
+   * Return the result of resolving the given URI against the URI of the library, or {@code null} if
+   * the URI is not valid. If the URI is not valid, report the error.
+   * @param uriLiteral the string literal specifying the URI to be resolved
+   * @return the result of resolving the given URI against the URI of the library
+   */
+  Source getSource(StringLiteral uriLiteral) => getSource2(getStringValue(uriLiteral), uriLiteral.offset, uriLiteral.length);
+  /**
+   * Set whether this library explicitly imports core to match the given value.
+   * @param explicitlyImportsCore {@code true} if this library explicitly imports core
+   */
+  void set explicitlyImportsCore(bool explicitlyImportsCore2) {
+    this._explicitlyImportsCore = explicitlyImportsCore2;
+  }
+  /**
+   * Set the library element representing this library to the given library element.
+   * @param libraryElement the library element representing this library
+   */
+  void set libraryElement(LibraryElementImpl libraryElement2) {
+    this._libraryElement = libraryElement2;
+  }
+  String toString() => _librarySource.shortName;
+  /**
+   * Append the value of the given string literal to the given string builder.
+   * @param builder the builder to which the string's value is to be appended
+   * @param literal the string literal whose value is to be appended to the builder
+   * @throws IllegalArgumentException if the string is not a constant string without any string
+   * interpolation
+   */
+  void appendStringValue(StringBuffer builder, StringLiteral literal) {
+    if (literal is SimpleStringLiteral) {
+      builder.add(((literal as SimpleStringLiteral)).value);
+    } else if (literal is AdjacentStrings) {
+      for (StringLiteral stringLiteral in ((literal as AdjacentStrings)).strings) {
+        appendStringValue(builder, stringLiteral);
+      }
+    } else {
+      throw new IllegalArgumentException();
+    }
+  }
+  /**
+   * Return the result of resolving the given URI against the URI of the library, or {@code null} if
+   * the URI is not valid. If the URI is not valid, report the error.
+   * @param uri the URI to be resolved
+   * @param uriOffset the offset of the string literal representing the URI
+   * @param uriLength the length of the string literal representing the URI
+   * @return the result of resolving the given URI against the URI of the library
+   */
+  Source getSource2(String uri, int uriOffset, int uriLength) {
+    if (uri == null) {
+      _errorListener.onError(new AnalysisError.con2(_librarySource, uriOffset, uriLength, ResolverErrorCode.INVALID_URI, []));
+      return null;
+    }
+    return _librarySource.resolve(uri);
+  }
+  /**
+   * Return the value of the given string literal, or {@code null} if the string is not a constant
+   * string without any string interpolation.
+   * @param literal the string literal whose value is to be returned
+   * @return the value of the given string literal
+   */
+  String getStringValue(StringLiteral literal) {
+    StringBuffer builder = new StringBuffer();
+    try {
+      appendStringValue(builder, literal);
+    } on IllegalArgumentException catch (exception) {
+      return null;
+    }
+    return builder.toString();
+  }
+}
+/**
+ * Instances of the class {@code LibraryElementBuilder} build an element model for a single library.
+ */
+class LibraryElementBuilder {
+  /**
+   * The analysis context in which the element model will be built.
+   */
+  AnalysisContextImpl _analysisContext;
+  /**
+   * The listener to which errors will be reported.
+   */
+  AnalysisErrorListener _errorListener;
+  /**
+   * The name of the core library.
+   */
+  static String CORE_LIBRARY_URI = "dart:core";
+  /**
+   * The name of the function used as an entry point.
+   */
+  static String _ENTRY_POINT_NAME = "main";
+  /**
+   * Initialize a newly created library element builder.
+   * @param resolver the resolver for which the element model is being built
+   */
+  LibraryElementBuilder(LibraryResolver resolver) {
+    this._analysisContext = resolver.analysisContext;
+    this._errorListener = resolver.errorListener;
+  }
+  /**
+   * Build the library element for the given library.
+   * @param library the library for which an element model is to be built
+   * @return the library element that was built
+   * @throws AnalysisException if the analysis could not be performed
+   */
+  LibraryElementImpl buildLibrary(Library library) {
+    CompilationUnitBuilder builder = new CompilationUnitBuilder(_analysisContext, _errorListener);
+    Source librarySource2 = library.librarySource;
+    CompilationUnit definingCompilationUnit3 = library.definingCompilationUnit;
+    CompilationUnitElementImpl definingCompilationUnitElement = builder.buildCompilationUnit2(librarySource2, definingCompilationUnit3);
+    NodeList<Directive> directives3 = definingCompilationUnit3.directives;
+    LibraryIdentifier libraryNameNode = null;
+    bool hasPartDirective = false;
+    FunctionElement entryPoint = findEntryPoint(definingCompilationUnitElement);
+    List<ImportElement> imports = new List<ImportElement>();
+    List<ExportElement> exports = new List<ExportElement>();
+    List<Directive> directivesToResolve = new List<Directive>();
+    List<CompilationUnitElementImpl> sourcedCompilationUnits = new List<CompilationUnitElementImpl>();
+    for (Directive directive in directives3) {
+      if (directive is LibraryDirective) {
+        if (libraryNameNode == null) {
+          libraryNameNode = ((directive as LibraryDirective)).name;
+          directivesToResolve.add(directive);
+        }
+      } else if (directive is PartDirective) {
+        hasPartDirective = true;
+        StringLiteral partUri = ((directive as PartDirective)).uri;
+        Source partSource = library.getSource(partUri);
+        if (partSource != null) {
+          CompilationUnitElementImpl part = builder.buildCompilationUnit(partSource);
+          String partLibraryName = getPartLibraryName(library, partSource, directivesToResolve);
+          if (partLibraryName == null) {
+            _errorListener.onError(new AnalysisError.con2(librarySource2, partUri.offset, partUri.length, ResolverErrorCode.MISSING_PART_OF_DIRECTIVE, []));
+          } else if (libraryNameNode == null) {
+          } else if (libraryNameNode.name != partLibraryName) {
+            _errorListener.onError(new AnalysisError.con2(librarySource2, partUri.offset, partUri.length, ResolverErrorCode.PART_WITH_WRONG_LIBRARY_NAME, [partLibraryName]));
+          }
+          if (entryPoint == null) {
+            entryPoint = findEntryPoint(part);
+          }
+          directive.element = part;
+          sourcedCompilationUnits.add(part);
+        }
+      }
+    }
+    if (hasPartDirective && libraryNameNode == null) {
+      _errorListener.onError(new AnalysisError.con1(librarySource2, ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART, []));
+    }
+    LibraryElementImpl libraryElement = new LibraryElementImpl(_analysisContext, libraryNameNode);
+    libraryElement.definingCompilationUnit = definingCompilationUnitElement;
+    if (entryPoint != null) {
+      libraryElement.entryPoint = entryPoint;
+    }
+    libraryElement.imports = new List.from(imports);
+    libraryElement.exports = new List.from(exports);
+    libraryElement.parts = new List.from(sourcedCompilationUnits);
+    for (Directive directive in directivesToResolve) {
+      directive.element = libraryElement;
+    }
+    library.libraryElement = libraryElement;
+    return libraryElement;
+  }
+  /**
+   * Search the top-level functions defined in the given compilation unit for the entry point.
+   * @param element the compilation unit to be searched
+   * @return the entry point that was found, or {@code null} if the compilation unit does not define
+   * an entry point
+   */
+  FunctionElement findEntryPoint(CompilationUnitElementImpl element) {
+    for (FunctionElement function in element.functions) {
+      if (function.name == _ENTRY_POINT_NAME) {
+        return function;
+      }
+    }
+    return null;
+  }
+  /**
+   * Return the name of the library that the given part is declared to be a part of, or {@code null}if the part does not contain a part-of directive.
+   * @param library the library containing the part
+   * @param partSource the source representing the part
+   * @param directivesToResolve a list of directives that should be resolved to the library being
+   * built
+   * @return the name of the library that the given part is declared to be a part of
+   */
+  String getPartLibraryName(Library library, Source partSource, List<Directive> directivesToResolve) {
+    try {
+      CompilationUnit partUnit = library.getAST(partSource);
+      for (Directive directive in partUnit.directives) {
+        if (directive is PartOfDirective) {
+          directivesToResolve.add(directive);
+          LibraryIdentifier libraryName3 = ((directive as PartOfDirective)).libraryName;
+          if (libraryName3 != null) {
+            return libraryName3.name;
+          }
+        }
+      }
+    } on AnalysisException catch (exception) {
+    }
+    return null;
+  }
+}
+/**
+ * Instances of the class {@code LibraryResolver} are used to resolve one or more mutually dependent
+ * libraries within a single context.
+ */
+class LibraryResolver {
+  /**
+   * The analysis context in which the libraries are being analyzed.
+   */
+  AnalysisContextImpl _analysisContext;
+  /**
+   * The listener to which analysis errors will be reported.
+   */
+  AnalysisErrorListener _errorListener;
+  /**
+   * A source object representing the core library (dart:core).
+   */
+  Source _coreLibrarySource;
+  /**
+   * The object representing the core library.
+   */
+  Library _coreLibrary;
+  /**
+   * The object used to access the types from the core library.
+   */
+  TypeProvider _typeProvider;
+  /**
+   * A table mapping library sources to the information being maintained for those libraries.
+   */
+  Map<Source, Library> _libraryMap = new Map<Source, Library>();
+  /**
+   * A collection containing the libraries that are being resolved together.
+   */
+  Set<Library> _librariesInCycles;
+  /**
+   * Initialize a newly created library resolver to resolve libraries within the given context.
+   * @param analysisContext the analysis context in which the library is being analyzed
+   * @param errorListener the listener to which analysis errors will be reported
+   */
+  LibraryResolver(AnalysisContextImpl analysisContext, AnalysisErrorListener errorListener) {
+    this._analysisContext = analysisContext;
+    this._errorListener = errorListener;
+    _coreLibrarySource = analysisContext.sourceFactory.forUri(LibraryElementBuilder.CORE_LIBRARY_URI);
+  }
+  /**
+   * Return the analysis context in which the libraries are being analyzed.
+   * @return the analysis context in which the libraries are being analyzed
+   */
+  AnalysisContextImpl get analysisContext => _analysisContext;
+  /**
+   * Return the listener to which analysis errors will be reported.
+   * @return the listener to which analysis errors will be reported
+   */
+  AnalysisErrorListener get errorListener => _errorListener;
+  /**
+   * Resolve the library specified by the given source in the given context.
+   * <p>
+   * Note that because Dart allows circular imports between libraries, it is possible that more than
+   * one library will need to be resolved. In such cases the error listener can receive errors from
+   * multiple libraries.
+   * @param librarySource the source specifying the defining compilation unit of the library to be
+   * resolved
+   * @param fullAnalysis {@code true} if a full analysis should be performed
+   * @return the element representing the resolved library
+   * @throws AnalysisException if the library could not be resolved for some reason
+   */
+  LibraryElement resolveLibrary(Source librarySource, bool fullAnalysis) {
+    Library targetLibrary = createLibrary(librarySource);
+    _coreLibrary = _libraryMap[_coreLibrarySource];
+    if (_coreLibrary == null) {
+      _coreLibrary = createLibrary(_coreLibrarySource);
+    }
+    computeLibraryDependencies(targetLibrary);
+    _librariesInCycles = computeLibrariesInCycles(targetLibrary);
+    buildElementModels();
+    buildDirectiveModels();
+    _typeProvider = new TypeProviderImpl(_coreLibrary.libraryElement);
+    buildTypeHierarchies();
+    resolveReferencesAndTypes();
+    if (fullAnalysis) {
+    }
+    recordLibraryElements();
+    return targetLibrary.libraryElement;
+  }
+  /**
+   * Add a dependency to the given map from the referencing library to the referenced library.
+   * @param dependencyMap the map to which the dependency is to be added
+   * @param referencingLibrary the library that references the referenced library
+   * @param referencedLibrary the library referenced by the referencing library
+   */
+  void addDependencyToMap(Map<Library, List<Library>> dependencyMap, Library referencingLibrary, Library referencedLibrary) {
+    List<Library> dependentLibraries = dependencyMap[referencedLibrary];
+    if (dependentLibraries == null) {
+      dependentLibraries = new List<Library>();
+      dependencyMap[referencedLibrary] = dependentLibraries;
+    }
+    dependentLibraries.add(referencingLibrary);
+  }
+  /**
+   * Given a library that is part of a cycle that includes the root library, add to the given set of
+   * libraries all of the libraries reachable from the root library that are also included in the
+   * cycle.
+   * @param library the library to be added to the collection of libraries in cycles
+   * @param librariesInCycle a collection of the libraries that are in the cycle
+   * @param dependencyMap a table mapping libraries to the collection of libraries from which those
+   * libraries are referenced
+   */
+  void addLibrariesInCycle(Library library, Set<Library> librariesInCycle, Map<Library, List<Library>> dependencyMap) {
+    if (javaSetAdd(librariesInCycle, library)) {
+      List<Library> dependentLibraries = dependencyMap[library];
+      if (dependentLibraries != null) {
+        for (Library dependentLibrary in dependentLibraries) {
+          addLibrariesInCycle(dependentLibrary, librariesInCycle, dependencyMap);
+        }
+      }
+    }
+  }
+  /**
+   * Add the given library, and all libraries reachable from it that have not already been visited,
+   * to the given dependency map.
+   * @param library the library currently being added to the dependency map
+   * @param dependencyMap the dependency map being computed
+   * @param visitedLibraries the libraries that have already been visited, used to prevent infinite
+   * recursion
+   */
+  void addToDependencyMap(Library library, Map<Library, List<Library>> dependencyMap, Set<Library> visitedLibraries) {
+    if (javaSetAdd(visitedLibraries, library)) {
+      for (Library referencedLibrary in library.importsAndExports) {
+        addDependencyToMap(dependencyMap, library, referencedLibrary);
+        addToDependencyMap(referencedLibrary, dependencyMap, visitedLibraries);
+      }
+      if (!library.explicitlyImportsCore && library != _coreLibrary) {
+        addDependencyToMap(dependencyMap, library, _coreLibrary);
+      }
+    }
+  }
+  /**
+   * Build the element model representing the combinators declared by the given directive.
+   * @param directive the directive that declares the combinators
+   * @return an array containing the import combinators that were built
+   */
+  List<NamespaceCombinator> buildCombinators(NamespaceDirective directive) {
+    List<NamespaceCombinator> combinators = new List<NamespaceCombinator>();
+    for (Combinator combinator in directive.combinators) {
+      if (combinator is HideCombinator) {
+        HideCombinatorImpl hide = new HideCombinatorImpl();
+        hide.hiddenNames = getIdentifiers(((combinator as HideCombinator)).hiddenNames);
+        combinators.add(hide);
+      } else {
+        ShowCombinatorImpl show = new ShowCombinatorImpl();
+        show.shownNames = getIdentifiers(((combinator as ShowCombinator)).shownNames);
+        combinators.add(show);
+      }
+    }
+    return new List.from(combinators);
+  }
+  /**
+   * Every library now has a corresponding {@link LibraryElement}, so it is now possible to resolve
+   * the import and export directives.
+   * @throws AnalysisException if the defining compilation unit for any of the libraries could not
+   * be accessed
+   */
+  void buildDirectiveModels() {
+    for (Library library in _librariesInCycles) {
+      Map<String, PrefixElementImpl> nameToPrefixMap = new Map<String, PrefixElementImpl>();
+      List<ImportElement> imports = new List<ImportElement>();
+      List<ExportElement> exports = new List<ExportElement>();
+      for (Directive directive in library.definingCompilationUnit.directives) {
+        if (directive is ImportDirective) {
+          ImportDirective importDirective = (directive as ImportDirective);
+          Library importedLibrary = library.getImport(importDirective);
+          ImportElementImpl importElement = new ImportElementImpl();
+          importElement.combinators = buildCombinators(importDirective);
+          LibraryElement importedLibraryElement = importedLibrary.libraryElement;
+          if (importedLibraryElement != null) {
+            importElement.importedLibrary = importedLibraryElement;
+            directive.element = importedLibraryElement;
+          }
+          SimpleIdentifier prefixNode = ((directive as ImportDirective)).prefix;
+          if (prefixNode != null) {
+            String prefixName = prefixNode.name;
+            PrefixElementImpl prefix = nameToPrefixMap[prefixName];
+            if (prefix == null) {
+              prefix = new PrefixElementImpl(prefixNode);
+              nameToPrefixMap[prefixName] = prefix;
+            }
+            importElement.prefix = prefix;
+          }
+          imports.add(importElement);
+        } else if (directive is ExportDirective) {
+          ExportDirective exportDirective = (directive as ExportDirective);
+          ExportElementImpl exportElement = new ExportElementImpl();
+          exportElement.combinators = buildCombinators(exportDirective);
+          LibraryElement exportedLibrary = library.getExport(exportDirective).libraryElement;
+          if (exportedLibrary != null) {
+            exportElement.exportedLibrary = exportedLibrary;
+            directive.element = exportedLibrary;
+          }
+          exports.add(exportElement);
+        }
+      }
+      Source librarySource3 = library.librarySource;
+      if (!library.explicitlyImportsCore && _coreLibrarySource != librarySource3) {
+        ImportElementImpl importElement = new ImportElementImpl();
+        importElement.importedLibrary = _coreLibrary.libraryElement;
+        importElement.synthetic = true;
+        imports.add(importElement);
+      }
+      LibraryElementImpl libraryElement3 = library.libraryElement;
+      libraryElement3.imports = new List.from(imports);
+      libraryElement3.exports = new List.from(exports);
+    }
+  }
+  /**
+   * Build element models for all of the libraries in the current cycle.
+   * @throws AnalysisException if any of the element models cannot be built
+   */
+  void buildElementModels() {
+    for (Library library in _librariesInCycles) {
+      LibraryElementBuilder builder = new LibraryElementBuilder(this);
+      LibraryElementImpl libraryElement = builder.buildLibrary(library);
+      library.libraryElement = libraryElement;
+    }
+  }
+  /**
+   * Resolve the type hierarchy across all of the types declared in the libraries in the current
+   * cycle.
+   * @throws AnalysisException if any of the type hierarchies could not be resolved
+   */
+  void buildTypeHierarchies() {
+    for (Library library in _librariesInCycles) {
+      for (Source source in library.compilationUnitSources) {
+        TypeResolverVisitor visitor = new TypeResolverVisitor(library, source, _typeProvider);
+        library.getAST(source).accept(visitor);
+      }
+    }
+  }
+  /**
+   * Compute a dependency map of libraries reachable from the given library. A dependency map is a
+   * table that maps individual libraries to a list of the libraries that either import or export
+   * those libraries.
+   * <p>
+   * This map is used to compute all of the libraries involved in a cycle that include the root
+   * library. Given that we only add libraries that are reachable from the root library, when we
+   * work backward we are guaranteed to only get libraries in the cycle.
+   * @param library the library currently being added to the dependency map
+   */
+  Map<Library, List<Library>> computeDependencyMap(Library library) {
+    Map<Library, List<Library>> dependencyMap = new Map<Library, List<Library>>();
+    addToDependencyMap(library, dependencyMap, new Set<Library>());
+    return dependencyMap;
+  }
+  /**
+   * Return a collection containing all of the libraries reachable from the given library that are
+   * contained in a cycle that includes the given library.
+   * @param library the library that must be included in any cycles whose members are to be returned
+   * @return all of the libraries referenced by the given library that have a circular reference
+   * back to the given library
+   */
+  Set<Library> computeLibrariesInCycles(Library library) {
+    Map<Library, List<Library>> dependencyMap = computeDependencyMap(library);
+    Set<Library> librariesInCycle = new Set<Library>();
+    addLibrariesInCycle(library, librariesInCycle, dependencyMap);
+    return librariesInCycle;
+  }
+  /**
+   * Recursively traverse the libraries reachable from the given library, creating instances of the
+   * class {@link Library} to represent them, and record the references in the library objects.
+   * @param library the library to be processed to find libaries that have not yet been traversed
+   * @throws AnalysisException if some portion of the library graph could not be traversed
+   */
+  void computeLibraryDependencies(Library library) {
+    bool explicitlyImportsCore = false;
+    CompilationUnit unit = library.definingCompilationUnit;
+    for (Directive directive in unit.directives) {
+      if (directive is ImportDirective) {
+        ImportDirective importDirective = (directive as ImportDirective);
+        Source importedSource = library.getSource(importDirective.uri);
+        if (importedSource == _coreLibrarySource) {
+          explicitlyImportsCore = true;
+        }
+        Library importedLibrary = _libraryMap[importedSource];
+        if (importedLibrary == null) {
+          importedLibrary = createLibrary(importedSource);
+          computeLibraryDependencies(importedLibrary);
+        }
+        library.addImport(importDirective, importedLibrary);
+      } else if (directive is ExportDirective) {
+        ExportDirective exportDirective = (directive as ExportDirective);
+        Source exportedSource = library.getSource(exportDirective.uri);
+        Library exportedLibrary = _libraryMap[exportedSource];
+        if (exportedLibrary == null) {
+          exportedLibrary = createLibrary(exportedSource);
+          computeLibraryDependencies(exportedLibrary);
+        }
+        library.addExport(exportDirective, exportedLibrary);
+      }
+    }
+    library.explicitlyImportsCore = explicitlyImportsCore;
+    if (!explicitlyImportsCore && _coreLibrarySource != library.librarySource) {
+      Library importedLibrary = _libraryMap[_coreLibrarySource];
+      if (importedLibrary == null) {
+        importedLibrary = createLibrary(_coreLibrarySource);
+        computeLibraryDependencies(importedLibrary);
+      }
+    }
+  }
+  /**
+   * Create an object to represent the information about the library defined by the compilation unit
+   * with the given source.
+   * @param librarySource the source of the library's defining compilation unit
+   * @return the library object that was created
+   */
+  Library createLibrary(Source librarySource) {
+    Library library = new Library(_analysisContext, _errorListener, librarySource);
+    _libraryMap[librarySource] = library;
+    return library;
+  }
+  /**
+   * Return an array containing the lexical identifiers associated with the nodes in the given list.
+   * @param names the AST nodes representing the identifiers
+   * @return the lexical identifiers associated with the nodes in the list
+   */
+  List<String> getIdentifiers(NodeList<SimpleIdentifier> names) {
+    int count = names.length;
+    List<String> identifiers = new List<String>.fixedLength(count);
+    for (int i = 0; i < count; i++) {
+      identifiers[i] = names[i].name;
+    }
+    return identifiers;
+  }
+  /**
+   * As the final step in the process, record the resolved element models with the analysis context.
+   */
+  void recordLibraryElements() {
+    Map<Source, LibraryElement> elementMap = new Map<Source, LibraryElement>();
+    for (Library library in _librariesInCycles) {
+      elementMap[library.librarySource] = library.libraryElement;
+    }
+    _analysisContext.recordLibraryElements(elementMap);
+  }
+  /**
+   * Resolve the identifiers and perform type analysis in the libraries in the current cycle.
+   * @throws AnalysisException if any of the identifiers could not be resolved or if any of the
+   * libraries could not have their types analyzed
+   */
+  void resolveReferencesAndTypes() {
+    for (Library library in _librariesInCycles) {
+      resolveReferencesAndTypes2(library);
+    }
+  }
+  /**
+   * Resolve the identifiers and perform type analysis in the given library.
+   * @param library the library to be resolved
+   * @throws AnalysisException if any of the identifiers could not be resolved or if the types in
+   * the library cannot be analyzed
+   */
+  void resolveReferencesAndTypes2(Library library) {
+    for (Source source in library.compilationUnitSources) {
+      ResolverVisitor visitor = new ResolverVisitor(library, source, _typeProvider);
+      library.getAST(source).accept(visitor);
+    }
+  }
+}
+/**
+ * Instances of the class {@code ResolverVisitor} are used to resolve the nodes within a single
+ * compilation unit.
+ */
+class ResolverVisitor extends ScopedVisitor {
+  /**
+   * The object used to resolve the element associated with the current node.
+   */
+  ElementResolver _elementResolver;
+  /**
+   * The object used to compute the type associated with the current node.
+   */
+  StaticTypeAnalyzer _typeAnalyzer;
+  /**
+   * The class element representing the class containing the current node, or {@code null} if the
+   * current node is not contained in a class.
+   */
+  ClassElement _enclosingClass = null;
+  /**
+   * The element representing the function containing the current node, or {@code null} if the
+   * current node is not contained in a function.
+   */
+  ExecutableElement _enclosingFunction = null;
+  /**
+   * Initialize a newly created visitor to resolve the nodes in a compilation unit.
+   * @param library the library containing the compilation unit being resolved
+   * @param source the source representing the compilation unit being visited
+   * @param typeProvider the object used to access the types from the core library
+   */
+  ResolverVisitor(Library library, Source source, TypeProvider typeProvider) : super(library, source, typeProvider) {
+    this._elementResolver = new ElementResolver(this);
+    this._typeAnalyzer = new StaticTypeAnalyzer(this);
+  }
+  Object visitClassDeclaration(ClassDeclaration node) {
+    ClassElement outerType = _enclosingClass;
+    try {
+      _enclosingClass = node.element;
+      _typeAnalyzer.thisType = _enclosingClass == null ? null : _enclosingClass.type;
+      super.visitClassDeclaration(node);
+    } finally {
+      _typeAnalyzer.thisType = outerType == null ? null : outerType.type;
+      _enclosingClass = outerType;
+    }
+    return null;
+  }
+  Object visitFunctionDeclaration(FunctionDeclaration node) {
+    ExecutableElement outerFunction = _enclosingFunction;
+    try {
+      SimpleIdentifier functionName = node.name;
+      _enclosingFunction = (functionName.element as ExecutableElement);
+      super.visitFunctionDeclaration(node);
+    } finally {
+      _enclosingFunction = outerFunction;
+    }
+    return null;
+  }
+  Object visitFunctionExpression(FunctionExpression node) {
+    ExecutableElement outerFunction = _enclosingFunction;
+    try {
+      _enclosingFunction = node.element;
+      super.visitFunctionExpression(node);
+    } finally {
+      _enclosingFunction = outerFunction;
+    }
+    return null;
+  }
+  Object visitLibraryIdentifier(LibraryIdentifier node) => null;
+  Object visitMethodDeclaration(MethodDeclaration node) {
+    ExecutableElement outerFunction = _enclosingFunction;
+    try {
+      _enclosingFunction = node.element;
+      super.visitMethodDeclaration(node);
+    } finally {
+      _enclosingFunction = outerFunction;
+    }
+    return null;
+  }
+  Object visitNode(ASTNode node) {
+    node.visitChildren(this);
+    node.accept(_elementResolver);
+    node.accept(_typeAnalyzer);
+    return null;
+  }
+  Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+    SimpleIdentifier prefix6 = node.prefix;
+    if (prefix6 != null) {
+      prefix6.accept(this);
+    }
+    node.accept(_elementResolver);
+    node.accept(_typeAnalyzer);
+    return null;
+  }
+  Object visitPropertyAccess(PropertyAccess node) {
+    Expression target5 = node.target;
+    if (target5 != null) {
+      target5.accept(this);
+    }
+    node.accept(_elementResolver);
+    node.accept(_typeAnalyzer);
+    return null;
+  }
+  Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
+    ArgumentList argumentList11 = node.argumentList;
+    if (argumentList11 != null) {
+      argumentList11.accept(this);
+    }
+    node.accept(_elementResolver);
+    node.accept(_typeAnalyzer);
+    return null;
+  }
+  Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    ArgumentList argumentList12 = node.argumentList;
+    if (argumentList12 != null) {
+      argumentList12.accept(this);
+    }
+    node.accept(_elementResolver);
+    node.accept(_typeAnalyzer);
+    return null;
+  }
+  Object visitTypeName(TypeName node) => null;
+  /**
+   * Return the class element representing the class containing the current node, or {@code null} if
+   * the current node is not contained in a class.
+   * @return the class element representing the class containing the current node
+   */
+  ClassElement get enclosingClass => _enclosingClass;
+  /**
+   * Return the element representing the function containing the current node, or {@code null} if
+   * the current node is not contained in a function.
+   * @return the element representing the function containing the current node
+   */
+  ExecutableElement get enclosingFunction => _enclosingFunction;
+}
+/**
+ * The abstract class {@code ScopedVisitor} maintains name and label scopes as an AST structure is
+ * being visited.
+ */
+abstract class ScopedVisitor extends GeneralizingASTVisitor<Object> {
+  /**
+   * The element for the library containing the compilation unit being visited.
+   */
+  LibraryElement _definingLibrary;
+  /**
+   * The source representing the compilation unit being visited.
+   */
+  Source _source;
+  /**
+   * The error listener that will be informed of any errors that are found during resolution.
+   */
+  AnalysisErrorListener _errorListener;
+  /**
+   * The scope used to resolve identifiers.
+   */
+  Scope _nameScope;
+  /**
+   * The object used to access the types from the core library.
+   */
+  TypeProvider _typeProvider;
+  /**
+   * The scope used to resolve labels for {@code break} and {@code continue} statements, or{@code null} if no labels have been defined in the current context.
+   */
+  LabelScope _labelScope;
+  /**
+   * Initialize a newly created visitor to resolve the nodes in a compilation unit.
+   * @param library the library containing the compilation unit being resolved
+   * @param source the source representing the compilation unit being visited
+   * @param typeProvider the object used to access the types from the core library
+   */
+  ScopedVisitor(Library library, Source source, TypeProvider typeProvider) {
+    this._definingLibrary = library.libraryElement;
+    this._source = source;
+    LibraryScope libraryScope2 = library.libraryScope;
+    this._errorListener = libraryScope2.errorListener;
+    this._nameScope = libraryScope2;
+    this._typeProvider = typeProvider;
+  }
+  /**
+   * Return the library element for the library containing the compilation unit being resolved.
+   * @return the library element for the library containing the compilation unit being resolved
+   */
+  LibraryElement get definingLibrary => _definingLibrary;
+  /**
+   * Return the object used to access the types from the core library.
+   * @return the object used to access the types from the core library
+   */
+  TypeProvider get typeProvider => _typeProvider;
+  Object visitBlock(Block node) {
+    Scope outerScope = _nameScope;
+    _nameScope = new EnclosedScope(_nameScope);
+    try {
+      super.visitBlock(node);
+    } finally {
+      _nameScope = outerScope;
+    }
+    return null;
+  }
+  Object visitClassDeclaration(ClassDeclaration node) {
+    Scope outerScope = _nameScope;
+    try {
+      _nameScope = new ClassScope(_nameScope, node.element);
+      super.visitClassDeclaration(node);
+    } finally {
+      _nameScope = outerScope;
+    }
+    return null;
+  }
+  Object visitClassTypeAlias(ClassTypeAlias node) {
+    Scope outerScope = _nameScope;
+    try {
+      _nameScope = new ClassScope(_nameScope, node.element);
+      super.visitClassTypeAlias(node);
+    } finally {
+      _nameScope = outerScope;
+    }
+    return null;
+  }
+  Object visitConstructorDeclaration(ConstructorDeclaration node) {
+    Scope outerScope = _nameScope;
+    try {
+      _nameScope = new FunctionScope(_nameScope, node.element);
+      super.visitConstructorDeclaration(node);
+    } finally {
+      _nameScope = outerScope;
+    }
+    return null;
+  }
+  Object visitDoStatement(DoStatement node) {
+    LabelScope outerScope = _labelScope;
+    _labelScope = new LabelScope.con1(outerScope, false, false);
+    try {
+      super.visitDoStatement(node);
+    } finally {
+      _labelScope = outerScope;
+    }
+    return null;
+  }
+  Object visitForEachStatement(ForEachStatement node) {
+    LabelScope outerScope = _labelScope;
+    _labelScope = new LabelScope.con1(outerScope, false, false);
+    try {
+      super.visitForEachStatement(node);
+    } finally {
+      _labelScope = outerScope;
+    }
+    return null;
+  }
+  Object visitForStatement(ForStatement node) {
+    LabelScope outerScope = _labelScope;
+    _labelScope = new LabelScope.con1(outerScope, false, false);
+    try {
+      super.visitForStatement(node);
+    } finally {
+      _labelScope = outerScope;
+    }
+    return null;
+  }
+  Object visitFunctionDeclaration(FunctionDeclaration node) {
+    FunctionElement function = node.element;
+    Scope outerScope = _nameScope;
+    try {
+      _nameScope = new FunctionScope(_nameScope, function);
+      super.visitFunctionDeclaration(node);
+    } finally {
+      _nameScope = outerScope;
+    }
+    _nameScope.define(function);
+    return null;
+  }
+  Object visitFunctionExpression(FunctionExpression node) {
+    Scope outerScope = _nameScope;
+    try {
+      _nameScope = new FunctionScope(_nameScope, node.element);
+      super.visitFunctionExpression(node);
+    } finally {
+      _nameScope = outerScope;
+    }
+    return null;
+  }
+  Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+    Scope outerScope = _nameScope;
+    try {
+      _nameScope = new FunctionTypeScope(_nameScope, node.element);
+      super.visitFunctionTypeAlias(node);
+    } finally {
+      _nameScope = outerScope;
+    }
+    return null;
+  }
+  Object visitLabeledStatement(LabeledStatement node) {
+    LabelScope outerScope = addScopesFor(node.labels);
+    try {
+      super.visitLabeledStatement(node);
+    } finally {
+      _labelScope = outerScope;
+    }
+    return null;
+  }
+  Object visitMethodDeclaration(MethodDeclaration node) {
+    Scope outerScope = _nameScope;
+    try {
+      _nameScope = new FunctionScope(_nameScope, node.element);
+      super.visitMethodDeclaration(node);
+    } finally {
+      _nameScope = outerScope;
+    }
+    return null;
+  }
+  Object visitSwitchCase(SwitchCase node) {
+    node.expression.accept(this);
+    LabelScope outerLabelScope = addScopesFor(node.labels);
+    Scope outerNameScope = _nameScope;
+    _nameScope = new EnclosedScope(_nameScope);
+    try {
+      node.statements.accept(this);
+    } finally {
+      _nameScope = outerNameScope;
+      _labelScope = outerLabelScope;
+    }
+    return null;
+  }
+  Object visitSwitchDefault(SwitchDefault node) {
+    LabelScope outerLabelScope = addScopesFor(node.labels);
+    Scope outerNameScope = _nameScope;
+    _nameScope = new EnclosedScope(_nameScope);
+    try {
+      node.statements.accept(this);
+    } finally {
+      _nameScope = outerNameScope;
+      _labelScope = outerLabelScope;
+    }
+    return null;
+  }
+  Object visitSwitchStatement(SwitchStatement node) {
+    LabelScope outerScope = _labelScope;
+    _labelScope = new LabelScope.con1(outerScope, true, false);
+    for (SwitchMember member in node.members) {
+      for (Label label in member.labels) {
+        SimpleIdentifier labelName = label.label;
+        LabelElement labelElement = (labelName.element as LabelElement);
+        _labelScope = new LabelScope.con2(outerScope, labelName.name, labelElement);
+      }
+    }
+    try {
+      super.visitSwitchStatement(node);
+    } finally {
+      _labelScope = outerScope;
+    }
+    return null;
+  }
+  Object visitVariableDeclaration(VariableDeclaration node) {
+    if (node.parent.parent is! TopLevelVariableDeclaration) {
+      VariableElement element19 = node.element;
+      if (element19 != null) {
+        _nameScope.define(element19);
+      }
+    }
+    super.visitVariableDeclaration(node);
+    return null;
+  }
+  Object visitWhileStatement(WhileStatement node) {
+    LabelScope outerScope = _labelScope;
+    _labelScope = new LabelScope.con1(outerScope, false, false);
+    try {
+      super.visitWhileStatement(node);
+    } finally {
+      _labelScope = outerScope;
+    }
+    return null;
+  }
+  /**
+   * Return the label scope in which the current node is being resolved.
+   * @return the label scope in which the current node is being resolved
+   */
+  LabelScope get labelScope => _labelScope;
+  /**
+   * Return the name scope in which the current node is being resolved.
+   * @return the name scope in which the current node is being resolved
+   */
+  Scope get nameScope => _nameScope;
+  /**
+   * Report an error with the given error code and arguments.
+   * @param errorCode the error code of the error to be reported
+   * @param node the node specifying the location of the error
+   * @param arguments the arguments to the error, used to compose the error message
+   */
+  void reportError(ResolverErrorCode errorCode, ASTNode node, List<Object> arguments) {
+    _errorListener.onError(new AnalysisError.con2(_source, node.offset, node.length, errorCode, [arguments]));
+  }
+  /**
+   * Report an error with the given error code and arguments.
+   * @param errorCode the error code of the error to be reported
+   * @param token the token specifying the location of the error
+   * @param arguments the arguments to the error, used to compose the error message
+   */
+  void reportError2(ResolverErrorCode errorCode, Token token, List<Object> arguments) {
+    _errorListener.onError(new AnalysisError.con2(_source, token.offset, token.length, errorCode, [arguments]));
+  }
+  /**
+   * Add scopes for each of the given labels.
+   * @param labels the labels for which new scopes are to be added
+   * @return the scope that was in effect before the new scopes were added
+   */
+  LabelScope addScopesFor(NodeList<Label> labels) {
+    LabelScope outerScope = _labelScope;
+    for (Label label in labels) {
+      SimpleIdentifier labelNameNode = label.label;
+      String labelName = labelNameNode.name;
+      LabelElement labelElement = (labelNameNode.element as LabelElement);
+      _labelScope = new LabelScope.con2(_labelScope, labelName, labelElement);
+    }
+    return outerScope;
+  }
+}
+/**
+ * Instances of the class {@code StaticTypeAnalyzer} perform two type-related tasks. First, they
+ * compute the static type of every expression. Second, they look for any static type errors or
+ * warnings that might need to be generated. The requirements for the type analyzer are:
+ * <ol>
+ * <li>Every element that refers to types should be fully populated.
+ * <li>Every node representing an expression should be resolved to the Type of the expression.</li>
+ * </ol>
+ */
+class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
+  /**
+   * The resolver driving this participant.
+   */
+  ResolverVisitor _resolver;
+  /**
+   * The object providing access to the types defined by the language.
+   */
+  TypeProvider _typeProvider;
+  /**
+   * The type representing the class containing the nodes being analyzed, or {@code null} if the
+   * nodes are not within a class.
+   */
+  InterfaceType _thisType;
+  /**
+   * Initialize a newly created type analyzer.
+   * @param resolver the resolver driving this participant
+   */
+  StaticTypeAnalyzer(ResolverVisitor resolver) {
+    this._resolver = resolver;
+    _typeProvider = resolver.typeProvider;
+  }
+  /**
+   * Set the type of the class being analyzed to the given type.
+   * @param thisType the type representing the class containing the nodes being analyzed
+   */
+  void set thisType(InterfaceType thisType2) {
+    this._thisType = thisType2;
+  }
+  /**
+   * The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is{@code String}.</blockquote>
+   */
+  Object visitAdjacentStrings(AdjacentStrings node) => recordType(node, _typeProvider.stringType);
+  /**
+   * The Dart Language Specification, 12.33: <blockquote>The static type of an argument definition
+   * test is {@code bool}.</blockquote>
+   */
+  Object visitArgumentDefinitionTest(ArgumentDefinitionTest node) => recordType(node, _typeProvider.boolType);
+  /**
+   * The Dart Language Specification, 12.32: <blockquote>... the cast expression <i>e as T</i> ...
+   * <p>
+   * It is a static warning if <i>T</i> does not denote a type available in the current lexical
+   * scope.
+   * <p>
+   * The static type of a cast expression <i>e as T</i> is <i>T</i>.</blockquote>
+   */
+  Object visitAsExpression(AsExpression node) => recordType(node, getType2(node.type));
+  /**
+   * The Dart Language Specification, 12.18: <blockquote> ... an assignment <i>a</i> of the form
+   * <i>v = e</i> ...
+   * <p>
+   * It is a static type warning if the static type of <i>e</i> may not be assigned to the static
+   * type of <i>v</i>.
+   * <p>
+   * The static type of the expression <i>v = e</i> is the static type of <i>e</i>.
+   * <p>
+   * ... an assignment of the form <i>C.v = e</i> ...
+   * <p>
+   * It is a static type warning if the static type of <i>e</i> may not be assigned to the static
+   * type of <i>C.v</i>.
+   * <p>
+   * The static type of the expression <i>C.v = e</i> is the static type of <i>e</i>.
+   * <p>
+   * ... an assignment of the form <i>e<sub>1</sub>.v = e<sub>2</sub></i> ...
+   * <p>
+   * Let <i>T</i> be the static type of <i>e<sub>1</sub></i>. It is a static type warning if
+   * <i>T</i> does not have an accessible instance setter named <i>v=</i>. It is a static type
+   * warning if the static type of <i>e<sub>2</sub></i> may not be assigned to <i>T</i>.
+   * <p>
+   * The static type of the expression <i>e<sub>1</sub>.v = e<sub>2</sub></i> is the static type of
+   * <i>e<sub>2</sub></i>.
+   * <p>
+   * ... an assignment of the form <i>e<sub>1</sub>[e<sub>2</sub>] = e<sub>3</sub></i> ...
+   * <p>
+   * The static type of the expression <i>e<sub>1</sub>[e<sub>2</sub>] = e<sub>3</sub></i> is the
+   * static type of <i>e<sub>3</sub></i>.
+   * <p>
+   * A compound assignment of the form <i>v op= e</i> is equivalent to <i>v = v op e</i>. A compound
+   * assignment of the form <i>C.v op= e</i> is equivalent to <i>C.v = C.v op e</i>. A compound
+   * assignment of the form <i>e<sub>1</sub>.v op= e<sub>2</sub></i> is equivalent to <i>((x) => x.v
+   * = x.v op e<sub>2</sub>)(e<sub>1</sub>)</i> where <i>x</i> is a variable that is not used in
+   * <i>e<sub>2</sub></i>. A compound assignment of the form <i>e<sub>1</sub>[e<sub>2</sub>] op=
+   * e<sub>3</sub></i> is equivalent to <i>((a, i) => a[i] = a[i] op e<sub>3</sub>)(e<sub>1</sub>,
+   * e<sub>2</sub>)</i> where <i>a</i> and <i>i</i> are a variables that are not used in
+   * <i>e<sub>3</sub></i>. </blockquote>
+   */
+  Object visitAssignmentExpression(AssignmentExpression node) {
+    TokenType operator11 = node.operator.type;
+    if (operator11 != TokenType.EQ) {
+      return recordReturnType(node, node.element);
+    }
+    Type2 leftType = getType(node.leftHandSide);
+    Type2 rightType = getType(node.rightHandSide);
+    if (!rightType.isAssignableTo(leftType)) {
+    }
+    return recordType(node, rightType);
+  }
+  /**
+   * The Dart Language Specification, 12.20: <blockquote>The static type of a logical boolean
+   * expression is {@code bool}.</blockquote>
+   * <p>
+   * The Dart Language Specification, 12.21:<blockquote>A bitwise expression of the form
+   * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocation
+   * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A bitwise expression of the form <i>super op
+   * e<sub>2</sub></i> is equivalent to the method invocation
+   * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
+   * <p>
+   * The Dart Language Specification, 12.22: <blockquote>The static type of an equality expression
+   * is {@code bool}.</blockquote>
+   * <p>
+   * The Dart Language Specification, 12.23: <blockquote>A relational expression of the form
+   * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocation
+   * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A relational expression of the form <i>super op
+   * e<sub>2</sub></i> is equivalent to the method invocation
+   * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
+   * <p>
+   * The Dart Language Specification, 12.24: <blockquote>A shift expression of the form
+   * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocation
+   * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A shift expression of the form <i>super op
+   * e<sub>2</sub></i> is equivalent to the method invocation
+   * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
+   * <p>
+   * The Dart Language Specification, 12.25: <blockquote>An additive expression of the form
+   * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocation
+   * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. An additive expression of the form <i>super op
+   * e<sub>2</sub></i> is equivalent to the method invocation
+   * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
+   * <p>
+   * The Dart Language Specification, 12.26: <blockquote>A multiplicative expression of the form
+   * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocation
+   * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A multiplicative expression of the form <i>super op
+   * e<sub>2</sub></i> is equivalent to the method invocation
+   * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
+   */
+  Object visitBinaryExpression(BinaryExpression node) {
+    TokenType operator12 = node.operator.type;
+    if (operator12 == TokenType.AMPERSAND_AMPERSAND || operator12 == TokenType.BAR_BAR || operator12 == TokenType.EQ_EQ || operator12 == TokenType.BANG_EQ) {
+      return recordType(node, _typeProvider.boolType);
+    }
+    return recordReturnType(node, node.element);
+  }
+  /**
+   * The Dart Language Specification, 12.4: <blockquote>The static type of a boolean literal is{@code bool}.</blockquote>
+   */
+  Object visitBooleanLiteral(BooleanLiteral node) => recordType(node, _typeProvider.boolType);
+  /**
+   * The Dart Language Specification, 12.15.2: <blockquote>A cascaded method invocation expression
+   * of the form <i>e..suffix</i> is equivalent to the expression <i>(t) {t.suffix; return
+   * t;}(e)</i>.</blockquote>
+   */
+  Object visitCascadeExpression(CascadeExpression node) => recordType(node, getType(node.target));
+  /**
+   * The Dart Language Specification, 12.19: <blockquote> ... a conditional expression <i>c</i> of
+   * the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub></i> ...
+   * <p>
+   * It is a static type warning if the type of e<sub>1</sub> may not be assigned to {@code bool}.
+   * <p>
+   * The static type of <i>c</i> is the least upper bound of the static type of <i>e<sub>2</sub></i>
+   * and the static type of <i>e<sub>3</sub></i>.</blockquote>
+   */
+  Object visitConditionalExpression(ConditionalExpression node) {
+    Type2 conditionType = getType(node.condition);
+    if (conditionType != null && !conditionType.isAssignableTo(_typeProvider.boolType)) {
+      _resolver.reportError(ResolverErrorCode.NON_BOOLEAN_CONDITION, node.condition, []);
+    }
+    Type2 thenType = getType(node.thenExpression);
+    Type2 elseType = getType(node.elseExpression);
+    if (thenType == null) {
+      return recordType(node, _typeProvider.dynamicType);
+    }
+    Type2 resultType = thenType.getLeastUpperBound(elseType);
+    return recordType(node, resultType);
+  }
+  /**
+   * The Dart Language Specification, 12.3: <blockquote>The static type of a literal double is{@code double}.</blockquote>
+   */
+  Object visitDoubleLiteral(DoubleLiteral node) => recordType(node, _typeProvider.doubleType);
+  /**
+   * The Dart Language Specification, 12.9: <blockquote>The static type of a function literal of the
+   * form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;, T<sub>n</sub> a<sub>n</sub>, [T<sub>n+1</sub>
+   * x<sub>n+1</sub> = d1, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub> = dk]) => e</i> is
+   * <i>(T<sub>1</sub>, &hellip;, Tn, [T<sub>n+1</sub> x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub>
+   * x<sub>n+k</sub>]) &rarr; T<sub>0</sub></i>, where <i>T<sub>0</sub></i> is the static type of
+   * <i>e</i>. In any case where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is
+   * considered to have been specified as dynamic.
+   * <p>
+   * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;,
+   * T<sub>n</sub> a<sub>n</sub>, {T<sub>n+1</sub> x<sub>n+1</sub> : d1, &hellip;, T<sub>n+k</sub>
+   * x<sub>n+k</sub> : dk}) => e</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {T<sub>n+1</sub>
+   * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>}) &rarr; T<sub>0</sub></i>, where
+   * <i>T<sub>0</sub></i> is the static type of <i>e</i>. In any case where <i>T<sub>i</sub>, 1
+   * &lt;= i &lt;= n</i>, is not specified, it is considered to have been specified as dynamic.
+   * <p>
+   * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;,
+   * T<sub>n</sub> a<sub>n</sub>, [T<sub>n+1</sub> x<sub>n+1</sub> = d1, &hellip;, T<sub>n+k</sub>
+   * x<sub>n+k</sub> = dk]) {s}</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, [T<sub>n+1</sub>
+   * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>]) &rarr; dynamic</i>. In any case
+   * where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is considered to have been
+   * specified as dynamic.
+   * <p>
+   * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;,
+   * T<sub>n</sub> a<sub>n</sub>, {T<sub>n+1</sub> x<sub>n+1</sub> : d1, &hellip;, T<sub>n+k</sub>
+   * x<sub>n+k</sub> : dk}) {s}</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {T<sub>n+1</sub>
+   * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>}) &rarr; dynamic</i>. In any case
+   * where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is considered to have been
+   * specified as dynamic.</blockquote>
+   */
+  Object visitFunctionExpression(FunctionExpression node) {
+    FunctionTypeImpl functionType = (node.element.type as FunctionTypeImpl);
+    setTypeInformation(functionType, computeReturnType(node), node.parameters);
+    return recordType(node, functionType);
+  }
+  /**
+   * The Dart Language Specification, 12.14.4: <blockquote>A function expression invocation <i>i</i>
+   * has the form <i>e<sub>f</sub>(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>:
+   * a<sub>n+1</sub>, &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>, where <i>e<sub>f</sub></i> is
+   * an expression.
+   * <p>
+   * It is a static type warning if the static type <i>F</i> of <i>e<sub>f</sub></i> may not be
+   * assigned to a function type.
+   * <p>
+   * If <i>F</i> is not a function type, the static type of <i>i</i> is dynamic. Otherwise the
+   * static type of <i>i</i> is the declared return type of <i>F</i>.</blockquote>
+   */
+  Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) => recordReturnType(node, node.element);
+  /**
+   * The Dart Language Specification, 12.29: <blockquote>An assignable expression of the form
+   * <i>e<sub>1</sub>[e<sub>2</sub>]</i> is evaluated as a method invocation of the operator method
+   * <i>[]</i> on <i>e<sub>1</sub></i> with argument <i>e<sub>2</sub></i>.</blockquote>
+   */
+  Object visitIndexExpression(IndexExpression node) => recordReturnType(node, node.element);
+  /**
+   * The Dart Language Specification, 12.11.1: <blockquote>The static type of a new expression of
+   * either the form <i>new T.id(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> or the form <i>new
+   * T(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> is <i>T</i>.</blockquote>
+   * <p>
+   * The Dart Language Specification, 12.11.2: <blockquote>The static type of a constant object
+   * expression of either the form <i>const T.id(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> or the
+   * form <i>const T(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> is <i>T</i>. </blockquote>
+   */
+  Object visitInstanceCreationExpression(InstanceCreationExpression node) => recordReturnType(node, node.element);
+  /**
+   * The Dart Language Specification, 12.3: <blockquote>The static type of an integer literal is{@code int}.</blockquote>
+   */
+  Object visitIntegerLiteral(IntegerLiteral node) => recordType(node, _typeProvider.intType);
+  /**
+   * The Dart Language Specification, 12.31: <blockquote>It is a static warning if <i>T</i> does not
+   * denote a type available in the current lexical scope.
+   * <p>
+   * The static type of an is-expression is {@code bool}.</blockquote>
+   */
+  Object visitIsExpression(IsExpression node) => recordType(node, _typeProvider.boolType);
+  /**
+   * The Dart Language Specification, 12.6: <blockquote>The static type of a list literal of the
+   * form <i><b>const</b> &lt;E&gt;[e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> or the form
+   * <i>&lt;E&gt;[e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> is {@code List&lt;E&gt;}. The static
+   * type a list literal of the form <i><b>const</b> [e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> or
+   * the form <i>[e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> is {@code List&lt;dynamic&gt;}.</blockquote>
+   */
+  Object visitListLiteral(ListLiteral node) {
+    TypeArgumentList typeArguments8 = node.typeArguments;
+    if (typeArguments8 != null) {
+      NodeList<TypeName> arguments3 = typeArguments8.arguments;
+      if (arguments3 != null && arguments3.length == 1) {
+        TypeName argumentType = arguments3[0];
+        return recordType(node, _typeProvider.listType.substitute5(<Type2> [getType2(argumentType)]));
+      }
+    }
+    return recordType(node, _typeProvider.listType.substitute5(<Type2> [_typeProvider.dynamicType]));
+  }
+  /**
+   * The Dart Language Specification, 12.7: <blockquote>The static type of a map literal of the form
+   * <i><b>const</b> &lt;String, V&gt; {k<sub>1</sub>:e<sub>1</sub>, &hellip;,
+   * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i>&lt;String, V&gt; {k<sub>1</sub>:e<sub>1</sub>,
+   * &hellip;, k<sub>n</sub>:e<sub>n</sub>}</i> is {@code Map&lt;String, V&gt;}. The static type a
+   * map literal of the form <i><b>const</b> {k<sub>1</sub>:e<sub>1</sub>, &hellip;,
+   * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i>{k<sub>1</sub>:e<sub>1</sub>, &hellip;,
+   * k<sub>n</sub>:e<sub>n</sub>}</i> is {@code Map&lt;String, dynamic&gt;}.
+   * <p>
+   * It is a compile-time error if the first type argument to a map literal is not
+   * <i>String</i>.</blockquote>
+   */
+  Object visitMapLiteral(MapLiteral node) {
+    TypeArgumentList typeArguments9 = node.typeArguments;
+    if (typeArguments9 != null) {
+      NodeList<TypeName> arguments4 = typeArguments9.arguments;
+      if (arguments4 != null && arguments4.length == 2) {
+        TypeName keyType = arguments4[0];
+        if (keyType != _typeProvider.stringType) {
+        }
+        TypeName valueType = arguments4[1];
+        return recordType(node, _typeProvider.mapType.substitute5(<Type2> [_typeProvider.stringType, getType2(valueType)]));
+      }
+    }
+    return recordType(node, _typeProvider.mapType.substitute5(<Type2> [_typeProvider.stringType, _typeProvider.dynamicType]));
+  }
+  /**
+   * The Dart Language Specification, 12.15.1: <blockquote>An ordinary method invocation <i>i</i>
+   * has the form <i>o.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>,
+   * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
+   * <p>
+   * Let <i>T</i> be the static type of <i>o</i>. It is a static type warning if <i>T</i> does not
+   * have an accessible instance member named <i>m</i>. If <i>T.m</i> exists, it is a static warning
+   * if the type <i>F</i> of <i>T.m</i> may not be assigned to a function type.
+   * <p>
+   * If <i>T.m</i> does not exist, or if <i>F</i> is not a function type, the static type of
+   * <i>i</i> is dynamic. Otherwise the static type of <i>i</i> is the declared return type of
+   * <i>F</i>.</blockquote>
+   * <p>
+   * The Dart Language Specification, 11.15.3: <blockquote>A static method invocation <i>i</i> has
+   * the form <i>C.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>,
+   * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
+   * <p>
+   * It is a static type warning if the type <i>F</i> of <i>C.m</i> may not be assigned to a
+   * function type.
+   * <p>
+   * If <i>F</i> is not a function type, or if <i>C.m</i> does not exist, the static type of i is
+   * dynamic. Otherwise the static type of <i>i</i> is the declared return type of
+   * <i>F</i>.</blockquote>
+   * <p>
+   * The Dart Language Specification, 11.15.4: <blockquote>A super method invocation <i>i</i> has
+   * the form <i>super.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>,
+   * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
+   * <p>
+   * It is a static type warning if <i>S</i> does not have an accessible instance member named m. If
+   * <i>S.m</i> exists, it is a static warning if the type <i>F</i> of <i>S.m</i> may not be
+   * assigned to a function type.
+   * <p>
+   * If <i>S.m</i> does not exist, or if <i>F</i> is not a function type, the static type of
+   * <i>i</i> is dynamic. Otherwise the static type of <i>i</i> is the declared return type of
+   * <i>F</i>.</blockquote>
+   */
+  Object visitMethodInvocation(MethodInvocation node) => recordReturnType(node, node.methodName.element);
+  Object visitNamedExpression(NamedExpression node) => recordType(node, getType(node.expression));
+  /**
+   * The Dart Language Specification, 12.2: <blockquote>The static type of {@code null} is bottom.
+   * </blockquote>
+   */
+  Object visitNullLiteral(NullLiteral node) => recordType(node, _typeProvider.bottomType);
+  Object visitParenthesizedExpression(ParenthesizedExpression node) => recordType(node, getType(node.expression));
+  /**
+   * The Dart Language Specification, 12.28: <blockquote>A postfix expression of the form
+   * <i>v++</i>, where <i>v</i> is an identifier, is equivalent to <i>(){var r = v; v = r + 1;
+   * return r}()</i>.
+   * <p>
+   * A postfix expression of the form <i>C.v++</i> is equivalent to <i>(){var r = C.v; C.v = r + 1;
+   * return r}()</i>.
+   * <p>
+   * A postfix expression of the form <i>e1.v++</i> is equivalent to <i>(x){var r = x.v; x.v = r +
+   * 1; return r}(e1)</i>.
+   * <p>
+   * A postfix expression of the form <i>e1[e2]++</i> is equivalent to <i>(a, i){var r = a[i]; a[i]
+   * = r + 1; return r}(e1, e2)</i>
+   * <p>
+   * A postfix expression of the form <i>v--</i>, where <i>v</i> is an identifier, is equivalent to
+   * <i>(){var r = v; v = r - 1; return r}()</i>.
+   * <p>
+   * A postfix expression of the form <i>C.v--</i> is equivalent to <i>(){var r = C.v; C.v = r - 1;
+   * return r}()</i>.
+   * <p>
+   * A postfix expression of the form <i>e1.v--</i> is equivalent to <i>(x){var r = x.v; x.v = r -
+   * 1; return r}(e1)</i>.
+   * <p>
+   * A postfix expression of the form <i>e1[e2]--</i> is equivalent to <i>(a, i){var r = a[i]; a[i]
+   * = r - 1; return r}(e1, e2)</i></blockquote>
+   */
+  Object visitPostfixExpression(PostfixExpression node) => recordType(node, getType(node.operand));
+  /**
+   * See {@link #visitSimpleIdentifier(SimpleIdentifier)}.
+   */
+  Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+    SimpleIdentifier prefixedIdentifier = node.identifier;
+    Element element20 = prefixedIdentifier.element;
+    if (element20 is VariableElement) {
+      Type2 variableType = ((element20 as VariableElement)).type;
+      recordType(prefixedIdentifier, variableType);
+      return recordType(node, variableType);
+    } else if (element20 is PropertyAccessorElement) {
+      Type2 propertyType = ((element20 as PropertyAccessorElement)).type.returnType;
+      recordType(prefixedIdentifier, propertyType);
+      return recordType(node, propertyType);
+    } else if (element20 is MethodElement) {
+      Type2 returnType = ((element20 as MethodElement)).type;
+      recordType(prefixedIdentifier, returnType);
+      return recordType(node, returnType);
+    } else {
+    }
+    recordType(prefixedIdentifier, _typeProvider.dynamicType);
+    return recordType(node, _typeProvider.dynamicType);
+  }
+  /**
+   * The Dart Language Specification, 12.27: <blockquote>A unary expression <i>u</i> of the form
+   * <i>op e</i> is equivalent to a method invocation <i>expression e.op()</i>. An expression of the
+   * form <i>op super</i> is equivalent to the method invocation <i>super.op()<i>.</blockquote>
+   */
+  Object visitPrefixExpression(PrefixExpression node) {
+    TokenType operator13 = node.operator.type;
+    if (identical(operator13, TokenType.BANG)) {
+      return recordType(node, _typeProvider.boolType);
+    }
+    return recordReturnType(node, node.element);
+  }
+  /**
+   * The Dart Language Specification, 12.13: <blockquote> Property extraction allows for a member of
+   * an object to be concisely extracted from the object. If <i>o</i> is an object, and if <i>m</i>
+   * is the name of a method member of <i>o</i>, then
+   * <ul>
+   * <li><i>o.m</i> is defined to be equivalent to: <i>(r<sub>1</sub>, &hellip;, r<sub>n</sub>,
+   * {p<sub>1</sub> : d<sub>1</sub>, &hellip;, p<sub>k</sub> : d<sub>k</sub>}){return
+   * o.m(r<sub>1</sub>, &hellip;, r<sub>n</sub>, p<sub>1</sub>: p<sub>1</sub>, &hellip;,
+   * p<sub>k</sub>: p<sub>k</sub>);}</i> if <i>m</i> has required parameters <i>r<sub>1</sub>,
+   * &hellip;, r<sub>n</sub></i>, and named parameters <i>p<sub>1</sub> &hellip; p<sub>k</sub></i>
+   * with defaults <i>d<sub>1</sub>, &hellip;, d<sub>k</sub></i>.</li>
+   * <li><i>(r<sub>1</sub>, &hellip;, r<sub>n</sub>, [p<sub>1</sub> = d<sub>1</sub>, &hellip;,
+   * p<sub>k</sub> = d<sub>k</sub>]){return o.m(r<sub>1</sub>, &hellip;, r<sub>n</sub>,
+   * p<sub>1</sub>, &hellip;, p<sub>k</sub>);}</i> if <i>m</i> has required parameters
+   * <i>r<sub>1</sub>, &hellip;, r<sub>n</sub></i>, and optional positional parameters
+   * <i>p<sub>1</sub> &hellip; p<sub>k</sub></i> with defaults <i>d<sub>1</sub>, &hellip;,
+   * d<sub>k</sub></i>.</li>
+   * </ul>
+   * Otherwise, if <i>m</i> is the name of a getter member of <i>o</i> (declared implicitly or
+   * explicitly) then <i>o.m</i> evaluates to the result of invoking the getter. </blockquote>
+   * <p>
+   * The Dart Language Specification, 12.17: <blockquote> ... a getter invocation <i>i</i> of the
+   * form <i>e.m</i> ...
+   * <p>
+   * Let <i>T</i> be the static type of <i>e</i>. It is a static type warning if <i>T</i> does not
+   * have a getter named <i>m</i>.
+   * <p>
+   * The static type of <i>i</i> is the declared return type of <i>T.m</i>, if <i>T.m</i> exists;
+   * otherwise the static type of <i>i</i> is dynamic.
+   * <p>
+   * ... a getter invocation <i>i</i> of the form <i>C.m</i> ...
+   * <p>
+   * It is a static warning if there is no class <i>C</i> in the enclosing lexical scope of
+   * <i>i</i>, or if <i>C</i> does not declare, implicitly or explicitly, a getter named <i>m</i>.
+   * <p>
+   * The static type of <i>i</i> is the declared return type of <i>C.m</i> if it exists or dynamic
+   * otherwise.
+   * <p>
+   * ... a top-level getter invocation <i>i</i> of the form <i>m</i>, where <i>m</i> is an
+   * identifier ...
+   * <p>
+   * The static type of <i>i</i> is the declared return type of <i>m</i>.</blockquote>
+   */
+  Object visitPropertyAccess(PropertyAccess node) {
+    SimpleIdentifier propertyName2 = node.propertyName;
+    Element element21 = propertyName2.element;
+    if (element21 is MethodElement) {
+      FunctionType type11 = ((element21 as MethodElement)).type;
+      recordType(propertyName2, type11);
+      return recordType(node, type11);
+    } else if (element21 is PropertyAccessorElement) {
+      PropertyAccessorElement accessor = (element21 as PropertyAccessorElement);
+      if (accessor.isGetter()) {
+        if (accessor.type == null) {
+          recordType(propertyName2, _typeProvider.dynamicType);
+          return recordType(node, _typeProvider.dynamicType);
+        }
+        Type2 returnType4 = accessor.type.returnType;
+        recordType(propertyName2, returnType4);
+        return recordType(node, returnType4);
+      } else {
+        recordType(propertyName2, VoidTypeImpl.instance);
+        return recordType(node, VoidTypeImpl.instance);
+      }
+    } else {
+    }
+    recordType(propertyName2, _typeProvider.dynamicType);
+    return recordType(node, _typeProvider.dynamicType);
+  }
+  /**
+   * The Dart Language Specification, 12.30: <blockquote>Evaluation of an identifier expression
+   * <i>e</i> of the form <i>id</i> proceeds as follows:
+   * <p>
+   * Let <i>d</i> be the innermost declaration in the enclosing lexical scope whose name is
+   * <i>id</i>. If no such declaration exists in the lexical scope, let <i>d</i> be the declaration
+   * of the inherited member named <i>id</i> if it exists.
+   * <ul>
+   * <li>If <i>d</i> is a class or type alias <i>T</i>, the value of <i>e</i> is the unique instance
+   * of class {@code Type} reifying <i>T</i>.
+   * <li>If <i>d</i> is a type parameter <i>T</i>, then the value of <i>e</i> is the value of the
+   * actual type argument corresponding to <i>T</i> that was passed to the generative constructor
+   * that created the current binding of this. We are assured that this is well defined, because if
+   * we were in a static member the reference to <i>T</i> would be a compile-time error.
+   * <li>If <i>d</i> is a library variable then:
+   * <ul>
+   * <li>If <i>d</i> is of one of the forms <i>var v = e<sub>i</sub>;</i>, <i>T v =
+   * e<sub>i</sub>;</i>, <i>final v = e<sub>i</sub>;</i>, <i>final T v = e<sub>i</sub>;</i>, and no
+   * value has yet been stored into <i>v</i> then the initializer expression <i>e<sub>i</sub></i> is
+   * evaluated. If, during the evaluation of <i>e<sub>i</sub></i>, the getter for <i>v</i> is
+   * referenced, a CyclicInitializationError is thrown. If the evaluation succeeded yielding an
+   * object <i>o</i>, let <i>r = o</i>, otherwise let <i>r = null</i>. In any case, <i>r</i> is
+   * stored into <i>v</i>. The value of <i>e</i> is <i>r</i>.
+   * <li>If <i>d</i> is of one of the forms <i>const v = e;</i> or <i>const T v = e;</i> the result
+   * of the getter is the value of the compile time constant <i>e</i>. Otherwise
+   * <li><i>e</i> evaluates to the current binding of <i>id</i>.
+   * </ul>
+   * <li>If <i>d</i> is a local variable or formal parameter then <i>e</i> evaluates to the current
+   * binding of <i>id</i>.
+   * <li>If <i>d</i> is a static method, top level function or local function then <i>e</i>
+   * evaluates to the function defined by <i>d</i>.
+   * <li>If <i>d</i> is the declaration of a static variable or static getter declared in class
+   * <i>C</i>, then <i>e</i> is equivalent to the getter invocation <i>C.id</i>.
+   * <li>If <i>d</i> is the declaration of a top level getter, then <i>e</i> is equivalent to the
+   * getter invocation <i>id</i>.
+   * <li>Otherwise, if <i>e</i> occurs inside a top level or static function (be it function,
+   * method, getter, or setter) or variable initializer, evaluation of e causes a NoSuchMethodError
+   * to be thrown.
+   * <li>Otherwise <i>e</i> is equivalent to the property extraction <i>this.id</i>.
+   * </ul>
+   * </blockquote>
+   */
+  Object visitSimpleIdentifier(SimpleIdentifier node) {
+    Element element22 = node.element;
+    if (element22 == null) {
+      return recordType(node, _typeProvider.dynamicType);
+    } else if (element22 is ClassElement) {
+      if (isTypeName(node)) {
+        return recordType(node, ((element22 as ClassElement)).type);
+      }
+      return recordType(node, _typeProvider.typeType);
+    } else if (element22 is TypeVariableElement) {
+      return recordType(node, ((element22 as TypeVariableElement)).type);
+    } else if (element22 is TypeAliasElement) {
+      return recordType(node, ((element22 as TypeAliasElement)).type);
+    } else if (element22 is VariableElement) {
+      return recordType(node, ((element22 as VariableElement)).type);
+    } else if (element22 is MethodElement) {
+      return recordType(node, ((element22 as MethodElement)).type);
+    } else if (element22 is PropertyAccessorElement) {
+      PropertyAccessorElement accessor = (element22 as PropertyAccessorElement);
+      if (accessor.isGetter()) {
+        return recordType(node, accessor.type.returnType);
+      } else {
+        return recordType(node, accessor.type.normalParameterTypes[0]);
+      }
+    } else if (element22 is ExecutableElement) {
+      return recordType(node, ((element22 as ExecutableElement)).type);
+    } else if (element22 is PrefixElement) {
+      return null;
+    } else {
+      return recordType(node, _typeProvider.dynamicType);
+    }
+  }
+  /**
+   * The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is{@code String}.</blockquote>
+   */
+  Object visitSimpleStringLiteral(SimpleStringLiteral node) => recordType(node, _typeProvider.stringType);
+  /**
+   * The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is{@code String}.</blockquote>
+   */
+  Object visitStringInterpolation(StringInterpolation node) => recordType(node, _typeProvider.stringType);
+  Object visitSuperExpression(SuperExpression node) => recordType(node, _thisType == null ? _typeProvider.dynamicType : _thisType.superclass);
+  /**
+   * The Dart Language Specification, 12.10: <blockquote>The static type of {@code this} is the
+   * interface of the immediately enclosing class.</blockquote>
+   */
+  Object visitThisExpression(ThisExpression node) => recordType(node, _thisType);
+  /**
+   * The Dart Language Specification, 12.8: <blockquote>The static type of a throw expression is
+   * bottom.</blockquote>
+   */
+  Object visitThrowExpression(ThrowExpression node) => recordType(node, _typeProvider.bottomType);
+  /**
+   * Given a function expression, compute the return type of the function. The return type of
+   * functions with a block body is {@code dynamicType}, with an expression body it is the type of
+   * the expression.
+   * @param node the function expression whose return type is to be computed
+   * @return the return type that was computed
+   */
+  Type2 computeReturnType(FunctionExpression node) {
+    FunctionBody body4 = node.body;
+    if (body4 is ExpressionFunctionBody) {
+      return getType(((body4 as ExpressionFunctionBody)).expression);
+    }
+    return _typeProvider.dynamicType;
+  }
+  /**
+   * Return the type of the given expression that is to be used for type analysis.
+   * @param expression the expression whose type is to be returned
+   * @return the type of the given expression
+   */
+  Type2 getType(Expression expression) {
+    Type2 type = expression.staticType;
+    if (type == null) {
+      return _typeProvider.dynamicType;
+    }
+    return type;
+  }
+  /**
+   * Return the type represented by the given type name.
+   * @param typeName the type name representing the type to be returned
+   * @return the type represented by the type name
+   */
+  Type2 getType2(TypeName typeName) {
+    Type2 type12 = typeName.type;
+    if (type12 == null) {
+      return _typeProvider.dynamicType;
+    }
+    return type12;
+  }
+  /**
+   * Return {@code true} if the given node is being used as the name of a type.
+   * @param node the node being tested
+   * @return {@code true} if the given node is being used as the name of a type
+   */
+  bool isTypeName(SimpleIdentifier node) {
+    ASTNode parent8 = node.parent;
+    return parent8 is TypeName || (parent8 is PrefixedIdentifier && parent8.parent is TypeName) || (parent8 is MethodInvocation && identical(node, ((parent8 as MethodInvocation)).target));
+  }
+  /**
+   * Record that the static type of the given node is the return type of the method or function
+   * represented by the given element.
+   * @param expression the node whose type is to be recorded
+   * @param element the element representing the method or function invoked by the given node
+   */
+  Object recordReturnType(Expression expression, Element element) {
+    if (element is ExecutableElement) {
+      FunctionType type13 = ((element as ExecutableElement)).type;
+      if (type13 != null) {
+        return recordType(expression, type13.returnType);
+      }
+    } else if (element is VariableElement) {
+      Type2 variableType = ((element as VariableElement)).type;
+      if (variableType is FunctionType) {
+        return recordType(expression, ((variableType as FunctionType)).returnType);
+      }
+    }
+    return recordType(expression, _typeProvider.dynamicType);
+  }
+  /**
+   * Record that the static type of the given node is the given type.
+   * @param expression the node whose type is to be recorded
+   * @param type the static type of the node
+   */
+  Object recordType(Expression expression, Type2 type) {
+    if (type == null) {
+      expression.staticType = _typeProvider.dynamicType;
+    } else {
+      expression.staticType = type;
+    }
+    return null;
+  }
+  /**
+   * Set the return type and parameter type information for the given function type based on the
+   * given return type and parameter elements.
+   * @param functionType the function type to be filled in
+   * @param returnType the return type of the function, or {@code null} if no type was declared
+   * @param parameters the elements representing the parameters to the function
+   */
+  void setTypeInformation(FunctionTypeImpl functionType, Type2 returnType7, FormalParameterList parameterList) {
+    List<Type2> normalParameterTypes = new List<Type2>();
+    List<Type2> optionalParameterTypes = new List<Type2>();
+    LinkedHashMap<String, Type2> namedParameterTypes = new LinkedHashMap<String, Type2>();
+    if (parameterList != null) {
+      for (ParameterElement parameter in parameterList.elements) {
+        if (parameter.parameterKind == ParameterKind.REQUIRED) {
+          normalParameterTypes.add(parameter.type);
+        } else if (parameter.parameterKind == ParameterKind.POSITIONAL) {
+          optionalParameterTypes.add(parameter.type);
+        } else if (parameter.parameterKind == ParameterKind.NAMED) {
+          namedParameterTypes[parameter.name] = parameter.type;
+        }
+      }
+    }
+    functionType.normalParameterTypes = new List.from(normalParameterTypes);
+    functionType.optionalParameterTypes = new List.from(optionalParameterTypes);
+    functionType.namedParameterTypes = namedParameterTypes;
+    functionType.returnType = returnType7;
+  }
+}
+/**
+ * The interface {@code TypeProvider} defines the behavior of objects that provide access to types
+ * defined by the language.
+ */
+abstract class TypeProvider {
+  /**
+   * Return the type representing the built-in type 'bool'.
+   * @return the type representing the built-in type 'bool'
+   */
+  InterfaceType get boolType;
+  /**
+   * Return the type representing the type 'bottom'.
+   * @return the type representing the type 'bottom'
+   */
+  Type2 get bottomType;
+  /**
+   * Return the type representing the built-in type 'double'.
+   * @return the type representing the built-in type 'double'
+   */
+  InterfaceType get doubleType;
+  /**
+   * Return the type representing the built-in type 'dynamic'.
+   * @return the type representing the built-in type 'dynamic'
+   */
+  Type2 get dynamicType;
+  /**
+   * Return the type representing the built-in type 'Function'.
+   * @return the type representing the built-in type 'Function'
+   */
+  InterfaceType get functionType;
+  /**
+   * Return the type representing the built-in type 'int'.
+   * @return the type representing the built-in type 'int'
+   */
+  InterfaceType get intType;
+  /**
+   * Return the type representing the built-in type 'List'.
+   * @return the type representing the built-in type 'List'
+   */
+  InterfaceType get listType;
+  /**
+   * Return the type representing the built-in type 'Map'.
+   * @return the type representing the built-in type 'Map'
+   */
+  InterfaceType get mapType;
+  /**
+   * Return the type representing the built-in type 'Object'.
+   * @return the type representing the built-in type 'Object'
+   */
+  InterfaceType get objectType;
+  /**
+   * Return the type representing the built-in type 'StackTrace'.
+   * @return the type representing the built-in type 'StackTrace'
+   */
+  InterfaceType get stackTraceType;
+  /**
+   * Return the type representing the built-in type 'String'.
+   * @return the type representing the built-in type 'String'
+   */
+  InterfaceType get stringType;
+  /**
+   * Return the type representing the built-in type 'Type'.
+   * @return the type representing the built-in type 'Type'
+   */
+  InterfaceType get typeType;
+}
+/**
+ * Instances of the class {@code TypeProviderImpl} provide access to types defined by the language
+ * by looking for those types in the element model for the core library.
+ */
+class TypeProviderImpl implements TypeProvider {
+  /**
+   * The type representing the built-in type 'bool'.
+   */
+  InterfaceType _boolType;
+  /**
+   * The type representing the type 'bottom'.
+   */
+  Type2 _bottomType;
+  /**
+   * The type representing the built-in type 'double'.
+   */
+  InterfaceType _doubleType;
+  /**
+   * The type representing the built-in type 'dynamic'.
+   */
+  Type2 _dynamicType;
+  /**
+   * The type representing the built-in type 'Function'.
+   */
+  InterfaceType _functionType;
+  /**
+   * The type representing the built-in type 'int'.
+   */
+  InterfaceType _intType;
+  /**
+   * The type representing the built-in type 'List'.
+   */
+  InterfaceType _listType;
+  /**
+   * The type representing the built-in type 'Map'.
+   */
+  InterfaceType _mapType;
+  /**
+   * The type representing the built-in type 'Object'.
+   */
+  InterfaceType _objectType;
+  /**
+   * The type representing the built-in type 'StackTrace'.
+   */
+  InterfaceType _stackTraceType;
+  /**
+   * The type representing the built-in type 'String'.
+   */
+  InterfaceType _stringType;
+  /**
+   * The type representing the built-in type 'Type'.
+   */
+  InterfaceType _typeType;
+  /**
+   * Initialize a newly created type provider to provide the types defined in the given library.
+   * @param coreLibrary the element representing the core library (dart:core).
+   */
+  TypeProviderImpl(LibraryElement coreLibrary) {
+    initializeFrom(coreLibrary);
+  }
+  InterfaceType get boolType => _boolType;
+  Type2 get bottomType => _bottomType;
+  InterfaceType get doubleType => _doubleType;
+  Type2 get dynamicType => _dynamicType;
+  InterfaceType get functionType => _functionType;
+  InterfaceType get intType => _intType;
+  InterfaceType get listType => _listType;
+  InterfaceType get mapType => _mapType;
+  InterfaceType get objectType => _objectType;
+  InterfaceType get stackTraceType => _stackTraceType;
+  InterfaceType get stringType => _stringType;
+  InterfaceType get typeType => _typeType;
+  /**
+   * Return the type with the given name from the given namespace, or {@code null} if there is no
+   * class with the given name.
+   * @param namespace the namespace in which to search for the given name
+   * @param typeName the name of the type being searched for
+   * @return the type that was found
+   */
+  InterfaceType getType(Namespace namespace, String typeName) {
+    Element element = namespace.get(typeName);
+    if (element == null) {
+      AnalysisEngine.instance.logger.logInformation("No definition of type ${typeName}");
+      return null;
+    }
+    return ((element as ClassElement)).type;
+  }
+  /**
+   * Initialize the types provided by this type provider from the given library.
+   * @param library the library containing the definitions of the core types
+   */
+  void initializeFrom(LibraryElement library) {
+    Namespace namespace = new NamespaceBuilder().createPublicNamespace(library);
+    _boolType = getType(namespace, "bool");
+    _bottomType = BottomTypeImpl.instance;
+    _doubleType = getType(namespace, "double");
+    _dynamicType = DynamicTypeImpl.instance;
+    _functionType = getType(namespace, "Function");
+    _intType = getType(namespace, "int");
+    _listType = getType(namespace, "List");
+    _mapType = getType(namespace, "Map");
+    _objectType = getType(namespace, "Object");
+    _stackTraceType = getType(namespace, "StackTrace");
+    _stringType = getType(namespace, "String");
+    _typeType = getType(namespace, "Type");
+  }
+}
+/**
+ * Instances of the class {@code TypeResolverVisitor} are used to resolve the types associated with
+ * the elements in the element model. This includes the types of superclasses, mixins, interfaces,
+ * fields, methods, parameters, and local variables. As a side-effect, this also finishes building
+ * the type hierarchy.
+ */
+class TypeResolverVisitor extends ScopedVisitor {
+  /**
+   * Initialize a newly created visitor to resolve the nodes in a compilation unit.
+   * @param library the library containing the compilation unit being resolved
+   * @param source the source representing the compilation unit being visited
+   * @param typeProvider the object used to access the types from the core library
+   */
+  TypeResolverVisitor(Library library, Source source, TypeProvider typeProvider) : super(library, source, typeProvider) {
+  }
+  Object visitCatchClause(CatchClause node) {
+    super.visitCatchClause(node);
+    SimpleIdentifier exception = node.exceptionParameter;
+    if (exception != null) {
+      TypeName exceptionTypeName = node.exceptionType;
+      Type2 exceptionType;
+      if (exceptionTypeName == null) {
+        exceptionType = typeProvider.objectType;
+      } else {
+        exceptionType = getType(exceptionTypeName);
+      }
+      recordType(exception, exceptionType);
+      Element element23 = exception.element;
+      if (element23 is VariableElementImpl) {
+        ((element23 as VariableElementImpl)).type = exceptionType;
+      } else {
+      }
+    }
+    SimpleIdentifier stackTrace = node.stackTraceParameter;
+    if (stackTrace != null) {
+      recordType(stackTrace, typeProvider.stackTraceType);
+    }
+    return null;
+  }
+  Object visitClassDeclaration(ClassDeclaration node) {
+    super.visitClassDeclaration(node);
+    ClassElementImpl classElement = getClassElement(node.name);
+    InterfaceType superclassType = null;
+    ExtendsClause extendsClause4 = node.extendsClause;
+    if (extendsClause4 != null) {
+      superclassType = resolveType(extendsClause4.superclass, null, null, null);
+    }
+    if (classElement != null) {
+      if (superclassType == null) {
+        InterfaceType objectType2 = typeProvider.objectType;
+        if (classElement.type != objectType2) {
+          superclassType = objectType2;
+        }
+      }
+      classElement.supertype = superclassType;
+    }
+    resolve(classElement, node.withClause, node.implementsClause);
+    return null;
+  }
+  Object visitClassTypeAlias(ClassTypeAlias node) {
+    super.visitClassTypeAlias(node);
+    ClassElementImpl classElement = getClassElement(node.name);
+    InterfaceType superclassType = resolveType(node.superclass, null, null, null);
+    if (superclassType == null) {
+      superclassType = typeProvider.objectType;
+    }
+    if (classElement != null && superclassType != null) {
+      classElement.supertype = superclassType;
+    }
+    resolve(classElement, node.withClause, node.implementsClause);
+    return null;
+  }
+  Object visitConstructorDeclaration(ConstructorDeclaration node) {
+    super.visitConstructorDeclaration(node);
+    ExecutableElementImpl element24 = (node.element as ExecutableElementImpl);
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(element24);
+    setTypeInformation(type, null, element24.parameters);
+    type.returnType = ((element24.enclosingElement as ClassElement)).type;
+    element24.type = type;
+    return null;
+  }
+  Object visitDefaultFormalParameter(DefaultFormalParameter node) {
+    super.visitDefaultFormalParameter(node);
+    return null;
+  }
+  Object visitFieldFormalParameter(FieldFormalParameter node) {
+    super.visitFieldFormalParameter(node);
+    Element element25 = node.identifier.element;
+    if (element25 is ParameterElementImpl) {
+      ParameterElementImpl parameter = (element25 as ParameterElementImpl);
+      Type2 type;
+      TypeName typeName = node.type;
+      if (typeName == null) {
+        type = typeProvider.dynamicType;
+      } else {
+        type = getType(typeName);
+      }
+      parameter.type = type;
+    } else {
+    }
+    return null;
+  }
+  Object visitFunctionDeclaration(FunctionDeclaration node) {
+    super.visitFunctionDeclaration(node);
+    ExecutableElementImpl element26 = (node.element as ExecutableElementImpl);
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(element26);
+    setTypeInformation(type, node.returnType, element26.parameters);
+    element26.type = type;
+    return null;
+  }
+  Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+    super.visitFunctionTypeAlias(node);
+    TypeAliasElementImpl element27 = (node.element as TypeAliasElementImpl);
+    FunctionTypeImpl type14 = (element27.type as FunctionTypeImpl);
+    setTypeInformation(type14, node.returnType, element27.parameters);
+    return null;
+  }
+  Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    super.visitFunctionTypedFormalParameter(node);
+    ParameterElementImpl element28 = (node.identifier.element as ParameterElementImpl);
+    FunctionTypeImpl type = new FunctionTypeImpl.con1((null as ExecutableElement));
+    setTypeInformation(type, node.returnType, getElements(node.parameters));
+    element28.type = type;
+    return null;
+  }
+  Object visitMethodDeclaration(MethodDeclaration node) {
+    super.visitMethodDeclaration(node);
+    ExecutableElementImpl element29 = (node.element as ExecutableElementImpl);
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(element29);
+    setTypeInformation(type, node.returnType, element29.parameters);
+    element29.type = type;
+    return null;
+  }
+  Object visitSimpleFormalParameter(SimpleFormalParameter node) {
+    super.visitSimpleFormalParameter(node);
+    Type2 declaredType;
+    TypeName typeName = node.type;
+    if (typeName == null) {
+      declaredType = typeProvider.dynamicType;
+    } else {
+      declaredType = getType(typeName);
+    }
+    Element element30 = node.identifier.element;
+    if (element30 is ParameterElement) {
+      ((element30 as ParameterElementImpl)).type = declaredType;
+    } else {
+    }
+    return null;
+  }
+  Object visitTypeName(TypeName node) {
+    super.visitTypeName(node);
+    Identifier typeName = node.name;
+    Element element = nameScope.lookup(typeName, definingLibrary);
+    Type2 type = null;
+    if (element == null) {
+      DynamicTypeImpl dynamicType = DynamicTypeImpl.instance;
+      VoidTypeImpl voidType = VoidTypeImpl.instance;
+      if (typeName.name == dynamicType.name) {
+        element = dynamicType.element;
+        type = dynamicType;
+        setElement(typeName, element);
+      } else if (typeName.name == voidType.name) {
+        type = voidType;
+      } else {
+        ASTNode parent9 = node.parent;
+        if (typeName is PrefixedIdentifier && parent9 is ConstructorName) {
+          ConstructorName name = (parent9 as ConstructorName);
+          if (name.name == null) {
+            SimpleIdentifier prefix7 = ((typeName as PrefixedIdentifier)).prefix;
+            element = nameScope.lookup(prefix7, definingLibrary);
+            if (element is PrefixElement) {
+              return null;
+            } else if (element != null) {
+              name.name = ((typeName as PrefixedIdentifier)).identifier;
+              node.name = prefix7;
+              typeName = prefix7;
+            }
+          }
+        }
+      }
+    }
+    if (element == null && type == null) {
+      return null;
+    } else if (element is ClassElement) {
+      setElement(typeName, element);
+      type = ((element as ClassElement)).type;
+    } else if (element is TypeAliasElement) {
+      setElement(typeName, element);
+      type = ((element as TypeAliasElement)).type;
+    } else if (element is TypeVariableElement) {
+      setElement(typeName, element);
+      type = ((element as TypeVariableElement)).type;
+    } else if (type == null) {
+      return null;
+    }
+    if (type == null) {
+      return null;
+    }
+    TypeArgumentList argumentList = node.typeArguments;
+    if (argumentList != null) {
+      NodeList<TypeName> arguments5 = argumentList.arguments;
+      int argumentCount = arguments5.length;
+      List<Type2> parameters = getTypeArguments(type);
+      int parameterCount = parameters.length;
+      if (argumentCount != parameterCount) {
+      }
+      List<Type2> typeArguments = new List<Type2>(argumentCount);
+      for (int i = 0; i < argumentCount; i++) {
+        Type2 argumentType = getType(arguments5[i]);
+        if (argumentType != null) {
+          typeArguments.add(argumentType);
+        }
+      }
+      if (type is InterfaceTypeImpl) {
+        InterfaceTypeImpl interfaceType = (type as InterfaceTypeImpl);
+        argumentCount = typeArguments.length;
+        if (interfaceType.typeArguments.length == argumentCount) {
+          type = interfaceType.substitute5(new List.from(typeArguments));
+        } else {
+        }
+      } else if (type is FunctionTypeImpl) {
+        FunctionTypeImpl functionType = (type as FunctionTypeImpl);
+        argumentCount = typeArguments.length;
+        if (functionType.typeArguments.length == argumentCount) {
+          type = functionType.substitute4(new List.from(typeArguments));
+        } else {
+        }
+      } else {
+      }
+    } else {
+      List<Type2> parameters = getTypeArguments(type);
+      int parameterCount = parameters.length;
+      if (parameterCount > 0) {
+        DynamicTypeImpl dynamicType = DynamicTypeImpl.instance;
+        List<Type2> arguments = new List<Type2>.fixedLength(parameterCount);
+        for (int i = 0; i < parameterCount; i++) {
+          arguments[i] = dynamicType;
+        }
+        type = type.substitute2(arguments, parameters);
+      }
+    }
+    typeName.staticType = type;
+    node.type = type;
+    return null;
+  }
+  Object visitVariableDeclaration(VariableDeclaration node) {
+    super.visitVariableDeclaration(node);
+    Type2 declaredType;
+    TypeName typeName = ((node.parent as VariableDeclarationList)).type;
+    if (typeName == null) {
+      declaredType = typeProvider.dynamicType;
+    } else {
+      declaredType = getType(typeName);
+    }
+    Element element31 = node.name.element;
+    if (element31 is VariableElement) {
+      ((element31 as VariableElementImpl)).type = declaredType;
+      if (element31 is FieldElement) {
+        FieldElement field = (element31 as FieldElement);
+        PropertyAccessorElementImpl getter3 = (field.getter as PropertyAccessorElementImpl);
+        FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter3);
+        getterType.returnType = declaredType;
+        getter3.type = getterType;
+        PropertyAccessorElementImpl setter3 = (field.setter as PropertyAccessorElementImpl);
+        if (setter3 != null) {
+          FunctionTypeImpl setterType = new FunctionTypeImpl.con1(setter3);
+          setterType.returnType = VoidTypeImpl.instance;
+          setterType.normalParameterTypes = <Type2> [declaredType];
+          setter3.type = setterType;
+        }
+      }
+    } else {
+    }
+    return null;
+  }
+  /**
+   * Return the class element that represents the class whose name was provided.
+   * @param identifier the name from the declaration of a class
+   * @return the class element that represents the class
+   */
+  ClassElementImpl getClassElement(SimpleIdentifier identifier) {
+    if (identifier == null) {
+      return null;
+    }
+    Element element32 = identifier.element;
+    if (element32 is! ClassElementImpl) {
+      return null;
+    }
+    return (element32 as ClassElementImpl);
+  }
+  /**
+   * Return an array containing all of the elements associated with the parameters in the given
+   * list.
+   * @param parameterList the list of parameters whose elements are to be returned
+   * @return the elements associated with the parameters
+   */
+  List<ParameterElement> getElements(FormalParameterList parameterList) {
+    List<ParameterElement> elements = new List<ParameterElement>();
+    for (FormalParameter parameter in parameterList.parameters) {
+      ParameterElement element33 = (parameter.identifier.element as ParameterElement);
+      if (element33 != null) {
+        elements.add(element33);
+      }
+    }
+    return new List.from(elements);
+  }
+  /**
+   * Return the type represented by the given type name.
+   * @param typeName the type name representing the type to be returned
+   * @return the type represented by the type name
+   */
+  Type2 getType(TypeName typeName) => typeName.type;
+  /**
+   * Return the type arguments associated with the given type.
+   * @param type the type whole type arguments are to be returned
+   * @return the type arguments associated with the given type
+   */
+  List<Type2> getTypeArguments(Type2 type) {
+    if (type is InterfaceType) {
+      return ((type as InterfaceType)).typeArguments;
+    } else if (type is FunctionType) {
+      return ((type as FunctionType)).typeArguments;
+    }
+    return TypeImpl.EMPTY_ARRAY;
+  }
+  /**
+   * Record that the static type of the given node is the given type.
+   * @param expression the node whose type is to be recorded
+   * @param type the static type of the node
+   */
+  Object recordType(Expression expression, Type2 type) {
+    if (type == null) {
+      expression.staticType = typeProvider.dynamicType;
+    } else {
+      expression.staticType = type;
+    }
+    return null;
+  }
+  /**
+   * Resolve the types in the given with and implements clauses and associate those types with the
+   * given class element.
+   * @param classElement the class element with which the mixin and interface types are to be
+   * associated
+   * @param withClause the with clause to be resolved
+   * @param implementsClause the implements clause to be resolved
+   */
+  void resolve(ClassElementImpl classElement, WithClause withClause, ImplementsClause implementsClause) {
+    if (withClause != null) {
+      List<InterfaceType> mixinTypes2 = resolveTypes(withClause.mixinTypes, null, null, null);
+      if (classElement != null) {
+        classElement.mixins = mixinTypes2;
+      }
+    }
+    if (implementsClause != null) {
+      List<InterfaceType> interfaceTypes = resolveTypes(implementsClause.interfaces, null, null, null);
+      if (classElement != null) {
+        classElement.interfaces = interfaceTypes;
+      }
+    }
+  }
+  /**
+   * Return the type specified by the given name.
+   * @param typeName the type name specifying the type to be returned
+   * @param undefinedError the error to produce if the type name is not defined
+   * @param nonTypeError the error to produce if the type name is defined to be something other than
+   * a type
+   * @param nonInterfaceType the error to produce if the type is not an interface type
+   * @return the type specified by the type name
+   */
+  InterfaceType resolveType(TypeName typeName, ResolverErrorCode undefinedError, ResolverErrorCode nonTypeError, ResolverErrorCode nonInterfaceType) {
+    Identifier name15 = typeName.name;
+    Element element = nameScope.lookup(name15, definingLibrary);
+    if (element == null) {
+      reportError(undefinedError, name15, []);
+    } else if (element is ClassElement) {
+      Type2 classType = ((element as ClassElement)).type;
+      typeName.type = classType;
+      if (classType is InterfaceType) {
+        return (classType as InterfaceType);
+      }
+      reportError(nonInterfaceType, name15, []);
+    } else {
+      reportError(nonTypeError, name15, []);
+    }
+    return null;
+  }
+  /**
+   * Resolve the types in the given list of type names.
+   * @param typeNames the type names to be resolved
+   * @param undefinedError the error to produce if the type name is not defined
+   * @param nonTypeError the error to produce if the type name is defined to be something other than
+   * a type
+   * @param nonInterfaceType the error to produce if the type is not an interface type
+   * @return an array containing all of the types that were resolved.
+   */
+  List<InterfaceType> resolveTypes(NodeList<TypeName> typeNames, ResolverErrorCode undefinedError, ResolverErrorCode nonTypeError, ResolverErrorCode nonInterfaceType) {
+    List<InterfaceType> types = new List<InterfaceType>();
+    for (TypeName typeName in typeNames) {
+      InterfaceType type = resolveType(typeName, undefinedError, nonTypeError, nonInterfaceType);
+      if (type != null) {
+        types.add(type);
+      }
+    }
+    return new List.from(types);
+  }
+  void setElement(Identifier typeName, Element element41) {
+    if (element41 != null) {
+      typeName.element = element41;
+      if (typeName is PrefixedIdentifier) {
+        PrefixedIdentifier identifier = (typeName as PrefixedIdentifier);
+        identifier.identifier.element = element41;
+        SimpleIdentifier prefix8 = identifier.prefix;
+        Element prefixElement = nameScope.lookup(prefix8, definingLibrary);
+        if (prefixElement != null) {
+          prefix8.element = prefixElement;
+        }
+      }
+    }
+  }
+  /**
+   * Set the return type and parameter type information for the given function type based on the
+   * given return type and parameter elements.
+   * @param functionType the function type to be filled in
+   * @param returnType the return type of the function, or {@code null} if no type was declared
+   * @param parameters the elements representing the parameters to the function
+   */
+  void setTypeInformation(FunctionTypeImpl functionType, TypeName returnType8, List<ParameterElement> parameters) {
+    List<Type2> normalParameterTypes = new List<Type2>();
+    List<Type2> optionalParameterTypes = new List<Type2>();
+    LinkedHashMap<String, Type2> namedParameterTypes = new LinkedHashMap<String, Type2>();
+    for (ParameterElement parameter in parameters) {
+      if (parameter.parameterKind == ParameterKind.REQUIRED) {
+        normalParameterTypes.add(parameter.type);
+      } else if (parameter.parameterKind == ParameterKind.POSITIONAL) {
+        optionalParameterTypes.add(parameter.type);
+      } else if (parameter.parameterKind == ParameterKind.NAMED) {
+        namedParameterTypes[parameter.name] = parameter.type;
+      }
+    }
+    functionType.normalParameterTypes = new List.from(normalParameterTypes);
+    functionType.optionalParameterTypes = new List.from(optionalParameterTypes);
+    functionType.namedParameterTypes = namedParameterTypes;
+    if (returnType8 == null) {
+      functionType.returnType = typeProvider.dynamicType;
+    } else {
+      functionType.returnType = returnType8.type;
+    }
+  }
+}
+/**
+ * Instances of the class {@code ClassScope} implement the scope defined by a class.
+ */
+class ClassScope extends EnclosedScope {
+  /**
+   * Initialize a newly created scope enclosed within another scope.
+   * @param enclosingScope the scope in which this scope is lexically enclosed
+   * @param typeElement the element representing the type represented by this scope
+   */
+  ClassScope(Scope enclosingScope, ClassElement typeElement) : super(new EnclosedScope(enclosingScope)) {
+    defineTypeParameters(typeElement);
+    defineMembers(typeElement);
+  }
+  /**
+   * Define the instance members defined by the class.
+   * @param typeElement the element representing the type represented by this scope
+   */
+  void defineMembers(ClassElement typeElement) {
+    for (PropertyAccessorElement accessor in typeElement.accessors) {
+      define(accessor);
+    }
+    for (FieldElement field in typeElement.fields) {
+      define(field);
+    }
+    for (MethodElement method in typeElement.methods) {
+      define(method);
+    }
+  }
+  /**
+   * Define the type parameters for the class.
+   * @param typeElement the element representing the type represented by this scope
+   */
+  void defineTypeParameters(ClassElement typeElement) {
+    Scope parameterScope = enclosingScope;
+    for (TypeVariableElement parameter in typeElement.typeVariables) {
+      parameterScope.define(parameter);
+    }
+  }
+}
+/**
+ * Instances of the class {@code EnclosedScope} implement a scope that is lexically enclosed in
+ * another scope.
+ */
+class EnclosedScope extends Scope {
+  /**
+   * The scope in which this scope is lexically enclosed.
+   */
+  Scope _enclosingScope;
+  /**
+   * Initialize a newly created scope enclosed within another scope.
+   * @param enclosingScope the scope in which this scope is lexically enclosed
+   */
+  EnclosedScope(Scope enclosingScope) {
+    this._enclosingScope = enclosingScope;
+  }
+  LibraryElement get definingLibrary => _enclosingScope.definingLibrary;
+  AnalysisErrorListener get errorListener => _enclosingScope.errorListener;
+  /**
+   * Return the scope in which this scope is lexically enclosed.
+   * @return the scope in which this scope is lexically enclosed
+   */
+  Scope get enclosingScope => _enclosingScope;
+  Element lookup3(String name, LibraryElement referencingLibrary) {
+    Element element = localLookup(name, referencingLibrary);
+    if (element != null) {
+      return element;
+    }
+    return _enclosingScope.lookup3(name, referencingLibrary);
+  }
+}
+/**
+ * Instances of the class {@code FunctionScope} implement the scope defined by a function.
+ */
+class FunctionScope extends EnclosedScope {
+  /**
+   * Initialize a newly created scope enclosed within another scope.
+   * @param enclosingScope the scope in which this scope is lexically enclosed
+   * @param functionElement the element representing the type represented by this scope
+   */
+  FunctionScope(Scope enclosingScope, ExecutableElement functionElement) : super(new EnclosedScope(enclosingScope)) {
+    defineParameters(functionElement);
+  }
+  /**
+   * Define the parameters for the given function in the scope that encloses this function.
+   * @param functionElement the element representing the function represented by this scope
+   */
+  void defineParameters(ExecutableElement functionElement) {
+    Scope parameterScope = enclosingScope;
+    if (functionElement.enclosingElement is ExecutableElement) {
+      String name16 = functionElement.name;
+      if (name16 != null && !name16.isEmpty) {
+        parameterScope.define(functionElement);
+      }
+    }
+    for (ParameterElement parameter in functionElement.parameters) {
+      if (!parameter.isInitializingFormal()) {
+        parameterScope.define(parameter);
+      }
+    }
+  }
+}
+/**
+ * Instances of the class {@code FunctionTypeScope} implement the scope defined by a function type
+ * alias.
+ */
+class FunctionTypeScope extends EnclosedScope {
+  /**
+   * Initialize a newly created scope enclosed within another scope.
+   * @param enclosingScope the scope in which this scope is lexically enclosed
+   * @param typeElement the element representing the type alias represented by this scope
+   */
+  FunctionTypeScope(Scope enclosingScope, TypeAliasElement typeElement) : super(new EnclosedScope(enclosingScope)) {
+    defineTypeParameters(typeElement);
+  }
+  /**
+   * Define the type parameters for the function type alias.
+   * @param typeElement the element representing the type represented by this scope
+   */
+  void defineTypeParameters(TypeAliasElement typeElement) {
+    Scope parameterScope = enclosingScope;
+    for (TypeVariableElement parameter in typeElement.typeVariables) {
+      parameterScope.define(parameter);
+    }
+  }
+}
+/**
+ * Instances of the class {@code LabelScope} represent a scope in which a single label is defined.
+ */
+class LabelScope {
+  /**
+   * The label scope enclosing this label scope.
+   */
+  LabelScope _outerScope;
+  /**
+   * The label defined in this scope.
+   */
+  String _label;
+  /**
+   * The element to which the label resolves.
+   */
+  LabelElement _element;
+  /**
+   * The marker used to look up a label element for an unlabeled {@code break} or {@code continue}.
+   */
+  static String EMPTY_LABEL = "";
+  /**
+   * The label element returned for scopes that can be the target of an unlabeled {@code break} or{@code continue}.
+   */
+  static SimpleIdentifier _EMPTY_LABEL_IDENTIFIER = new SimpleIdentifier.full(new StringToken(TokenType.IDENTIFIER, "", 0));
+  /**
+   * Initialize a newly created scope to represent the potential target of an unlabeled{@code break} or {@code continue}.
+   * @param outerScope the label scope enclosing the new label scope
+   * @param onSwitchStatement {@code true} if this label is associated with a {@code switch}statement
+   * @param onSwitchMember {@code true} if this label is associated with a {@code switch} member
+   */
+  LabelScope.con1(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMember) {
+    _jtd_constructor_198_impl(outerScope, onSwitchStatement, onSwitchMember);
+  }
+  _jtd_constructor_198_impl(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMember) {
+    _jtd_constructor_199_impl(outerScope, EMPTY_LABEL, new LabelElementImpl(_EMPTY_LABEL_IDENTIFIER, onSwitchStatement, onSwitchMember));
+  }
+  /**
+   * Initialize a newly created scope to represent the given label.
+   * @param outerScope the label scope enclosing the new label scope
+   * @param label the label defined in this scope
+   * @param element the element to which the label resolves
+   */
+  LabelScope.con2(LabelScope outerScope2, String label3, LabelElement element18) {
+    _jtd_constructor_199_impl(outerScope2, label3, element18);
+  }
+  _jtd_constructor_199_impl(LabelScope outerScope2, String label3, LabelElement element18) {
+    this._outerScope = outerScope2;
+    this._label = label3;
+    this._element = element18;
+  }
+  /**
+   * Return the label element corresponding to the given label, or {@code null} if the given label
+   * is not defined in this scope.
+   * @param targetLabel the label being looked up
+   * @return the label element corresponding to the given label
+   */
+  LabelElement lookup(SimpleIdentifier targetLabel) => lookup2(targetLabel.name);
+  /**
+   * Return the label element corresponding to the given label, or {@code null} if the given label
+   * is not defined in this scope.
+   * @param targetLabel the label being looked up
+   * @return the label element corresponding to the given label
+   */
+  LabelElement lookup2(String targetLabel) {
+    if (_label == targetLabel) {
+      return _element;
+    } else if (_outerScope != null) {
+      return _outerScope.lookup2(targetLabel);
+    } else {
+      return null;
+    }
+  }
+}
+/**
+ * Instances of the class {@code LibraryImportScope} represent the scope containing all of the names
+ * available from imported libraries.
+ */
+class LibraryImportScope extends Scope {
+  /**
+   * The element representing the library in which this scope is enclosed.
+   */
+  LibraryElement _definingLibrary;
+  /**
+   * The listener that is to be informed when an error is encountered.
+   */
+  AnalysisErrorListener _errorListener;
+  /**
+   * A list of the namespaces representing the names that are available in this scope from imported
+   * libraries.
+   */
+  List<Namespace> _importedNamespaces = new List<Namespace>();
+  /**
+   * Initialize a newly created scope representing the names imported into the given library.
+   * @param definingLibrary the element representing the library that imports the names defined in
+   * this scope
+   * @param errorListener the listener that is to be informed when an error is encountered
+   */
+  LibraryImportScope(LibraryElement definingLibrary, AnalysisErrorListener errorListener) {
+    this._definingLibrary = definingLibrary;
+    this._errorListener = errorListener;
+    createImportedNamespaces(definingLibrary);
+  }
+  void define(Element element) {
+    if (!Scope.isPrivateName(element.name)) {
+      super.define(element);
+    }
+  }
+  LibraryElement get definingLibrary => _definingLibrary;
+  AnalysisErrorListener get errorListener => _errorListener;
+  Element lookup3(String name, LibraryElement referencingLibrary) {
+    if (Scope.isPrivateName(name)) {
+      return null;
+    }
+    Element foundElement = localLookup(name, referencingLibrary);
+    if (foundElement != null) {
+      return foundElement;
+    }
+    for (Namespace nameSpace in _importedNamespaces) {
+      Element element = nameSpace.get(name);
+      if (element != null) {
+        if (foundElement == null) {
+          foundElement = element;
+        } else {
+          foundElement = new MultiplyDefinedElementImpl(_definingLibrary.context, foundElement, element);
+        }
+      }
+    }
+    if (foundElement != null) {
+      defineWithoutChecking(foundElement);
+    }
+    return foundElement;
+  }
+  /**
+   * Create all of the namespaces associated with the libraries imported into this library. The
+   * names are not added to this scope, but are stored for later reference.
+   * @param definingLibrary the element representing the library that imports the libraries for
+   * which namespaces will be created
+   */
+  void createImportedNamespaces(LibraryElement definingLibrary) {
+    NamespaceBuilder builder = new NamespaceBuilder();
+    for (ImportElement element in definingLibrary.imports) {
+      _importedNamespaces.add(builder.createImportNamespace(element));
+    }
+  }
+}
+/**
+ * Instances of the class {@code LibraryScope} implement a scope containing all of the names defined
+ * in a given library.
+ */
+class LibraryScope extends EnclosedScope {
+  /**
+   * Initialize a newly created scope representing the names defined in the given library.
+   * @param definingLibrary the element representing the library represented by this scope
+   * @param errorListener the listener that is to be informed when an error is encountered
+   */
+  LibraryScope(LibraryElement definingLibrary, AnalysisErrorListener errorListener) : super(new LibraryImportScope(definingLibrary, errorListener)) {
+    defineTopLevelNames(definingLibrary);
+  }
+  /**
+   * Add to this scope all of the public top-level names that are defined in the given compilation
+   * unit.
+   * @param compilationUnit the compilation unit defining the top-level names to be added to this
+   * scope
+   */
+  void defineLocalNames(CompilationUnitElement compilationUnit) {
+    for (PropertyAccessorElement element in compilationUnit.accessors) {
+      define(element);
+    }
+    for (FunctionElement element in compilationUnit.functions) {
+      define(element);
+    }
+    for (TypeAliasElement element in compilationUnit.typeAliases) {
+      define(element);
+    }
+    for (ClassElement element in compilationUnit.types) {
+      define(element);
+    }
+    for (VariableElement element in compilationUnit.variables) {
+      define(element);
+    }
+  }
+  /**
+   * Add to this scope all of the names that are explicitly defined in the given library.
+   * @param definingLibrary the element representing the library that defines the names in this
+   * scope
+   */
+  void defineTopLevelNames(LibraryElement definingLibrary) {
+    for (PrefixElement prefix in definingLibrary.prefixes) {
+      define(prefix);
+    }
+    defineLocalNames(definingLibrary.definingCompilationUnit);
+    for (CompilationUnitElement compilationUnit in definingLibrary.parts) {
+      defineLocalNames(compilationUnit);
+    }
+  }
+}
+/**
+ * Instances of the class {@code Namespace} implement a mapping of identifiers to the elements
+ * represented by those identifiers. Namespaces are the building blocks for scopes.
+ */
+class Namespace {
+  /**
+   * A table mapping names that are defined in this namespace to the element representing the thing
+   * declared with that name.
+   */
+  Map<String, Element> _definedNames = new Map<String, Element>();
+  /**
+   * Initialize a newly created namespace to have the given defined names.
+   * @param definedNames the mapping from names that are defined in this namespace to the
+   * corresponding elements
+   */
+  Namespace(Map<String, Element> definedNames) {
+    this._definedNames = definedNames;
+  }
+  /**
+   * Return the element in this namespace that is available to the containing scope using the given
+   * name.
+   * @param name the name used to reference the
+   * @return the element represented by the given identifier
+   */
+  Element get(String name) => _definedNames[name];
+  /**
+   * Return a table containing the same mappings as those defined by this namespace.
+   * @return a table containing the same mappings as those defined by this namespace
+   */
+  Map<String, Element> get definedNames => new Map<String, Element>();
+}
+/**
+ * Instances of the class {@code NamespaceBuilder} are used to build a {@code Namespace}. Namespace
+ * builders are thread-safe and re-usable.
+ */
+class NamespaceBuilder {
+  /**
+   * Initialize a newly created namespace builder.
+   */
+  NamespaceBuilder() : super() {
+  }
+  /**
+   * Create a namespace representing the export namespace of the given library.
+   * @param library the library whose export namespace is to be created
+   * @return the export namespace that was created
+   */
+  Namespace createExportNamespace(LibraryElement library) => new Namespace(createExportMapping(library, new Set<LibraryElement>()));
+  /**
+   * Create a namespace representing the import namespace of the given library.
+   * @param library the library whose import namespace is to be created
+   * @return the import namespace that was created
+   */
+  Namespace createImportNamespace(ImportElement element) {
+    Map<String, Element> definedNames = createExportMapping(element.importedLibrary, new Set<LibraryElement>());
+    definedNames = apply(definedNames, element.combinators);
+    definedNames = apply2(definedNames, element.prefix);
+    return new Namespace(definedNames);
+  }
+  /**
+   * Create a namespace representing the public namespace of the given library.
+   * @param library the library whose public namespace is to be created
+   * @return the public namespace that was created
+   */
+  Namespace createPublicNamespace(LibraryElement library) {
+    Map<String, Element> definedNames = new Map<String, Element>();
+    addPublicNames(definedNames, library.definingCompilationUnit);
+    for (CompilationUnitElement compilationUnit in library.parts) {
+      addPublicNames(definedNames, compilationUnit);
+    }
+    return new Namespace(definedNames);
+  }
+  /**
+   * Add all of the names in the given namespace to the given mapping table.
+   * @param definedNames the mapping table to which the names in the given namespace are to be added
+   * @param namespace the namespace containing the names to be added to this namespace
+   */
+  void addAll(Map<String, Element> definedNames, Map<String, Element> newNames) {
+    for (MapEntry<String, Element> entry in getMapEntrySet(newNames)) {
+      definedNames[entry.getKey()] = entry.getValue();
+    }
+  }
+  /**
+   * Add all of the names in the given namespace to the given mapping table.
+   * @param definedNames the mapping table to which the names in the given namespace are to be added
+   * @param namespace the namespace containing the names to be added to this namespace
+   */
+  void addAll2(Map<String, Element> definedNames2, Namespace namespace) {
+    addAll(definedNames2, namespace.definedNames);
+  }
+  /**
+   * Add the given element to the given mapping table if it has a publicly visible name.
+   * @param definedNames the mapping table to which the public name is to be added
+   * @param element the element to be added
+   */
+  void addIfPublic(Map<String, Element> definedNames, Element element) {
+    String name17 = element.name;
+    if (name17 != null && !Scope.isPrivateName(name17)) {
+      definedNames[name17] = element;
+    }
+  }
+  /**
+   * Add to the given mapping table all of the public top-level names that are defined in the given
+   * compilation unit.
+   * @param definedNames the mapping table to which the public names are to be added
+   * @param compilationUnit the compilation unit defining the top-level names to be added to this
+   * namespace
+   */
+  void addPublicNames(Map<String, Element> definedNames, CompilationUnitElement compilationUnit) {
+    for (PropertyAccessorElement element in compilationUnit.accessors) {
+      addIfPublic(definedNames, element);
+    }
+    for (FunctionElement element in compilationUnit.functions) {
+      addIfPublic(definedNames, element);
+    }
+    for (TypeAliasElement element in compilationUnit.typeAliases) {
+      addIfPublic(definedNames, element);
+    }
+    for (ClassElement element in compilationUnit.types) {
+      addIfPublic(definedNames, element);
+    }
+    for (VariableElement element in compilationUnit.variables) {
+      addIfPublic(definedNames, element);
+    }
+  }
+  /**
+   * Apply the given combinators to all of the names in the given mapping table.
+   * @param definedNames the mapping table to which the namespace operations are to be applied
+   * @param combinators the combinators to be applied
+   */
+  Map<String, Element> apply(Map<String, Element> definedNames, List<NamespaceCombinator> combinators) {
+    for (NamespaceCombinator combinator in combinators) {
+      if (combinator is __imp_combi.HideCombinator) {
+        hide(definedNames, ((combinator as __imp_combi.HideCombinator)).hiddenNames);
+      } else if (combinator is __imp_combi.ShowCombinator) {
+        definedNames = show(definedNames, ((combinator as __imp_combi.ShowCombinator)).shownNames);
+      } else {
+        AnalysisEngine.instance.logger.logError("Unknown type of combinator: ${combinator.runtimeType.toString()}");
+      }
+    }
+    return definedNames;
+  }
+  /**
+   * Apply the given prefix to all of the names in the table of defined names.
+   * @param definedNames the names that were defined before this operation
+   * @param prefixElement the element defining the prefix to be added to the names
+   */
+  Map<String, Element> apply2(Map<String, Element> definedNames, PrefixElement prefixElement) {
+    if (prefixElement != null) {
+      String prefix = prefixElement.name;
+      Map<String, Element> newNames = new Map<String, Element>();
+      for (MapEntry<String, Element> entry in getMapEntrySet(definedNames)) {
+        newNames["${prefix}.${entry.getKey()}"] = entry.getValue();
+      }
+      return newNames;
+    } else {
+      return definedNames;
+    }
+  }
+  /**
+   * Create a mapping table representing the export namespace of the given library.
+   * @param library the library whose public namespace is to be created
+   * @param visitedElements a set of libraries that do not need to be visited when processing the
+   * export directives of the given library because all of the names defined by them will
+   * be added by another library
+   * @return the mapping table that was created
+   */
+  Map<String, Element> createExportMapping(LibraryElement library, Set<LibraryElement> visitedElements) {
+    javaSetAdd(visitedElements, library);
+    try {
+      Map<String, Element> definedNames = new Map<String, Element>();
+      for (ExportElement element in library.exports) {
+        LibraryElement exportedLibrary3 = element.exportedLibrary;
+        if (!visitedElements.contains(exportedLibrary3)) {
+          Map<String, Element> exportedNames = createExportMapping(exportedLibrary3, visitedElements);
+          exportedNames = apply(exportedNames, element.combinators);
+          addAll(definedNames, exportedNames);
+        }
+      }
+      addAll2(definedNames, ((library.context as AnalysisContextImpl)).getPublicNamespace(library));
+      return definedNames;
+    } finally {
+      visitedElements.remove(library);
+    }
+  }
+  /**
+   * Hide all of the given names by removing them from the given collection of defined names.
+   * @param definedNames the names that were defined before this operation
+   * @param hiddenNames the names to be hidden
+   */
+  void hide(Map<String, Element> definedNames, List<String> hiddenNames) {
+    for (String name in hiddenNames) {
+      definedNames.remove(name);
+    }
+  }
+  /**
+   * Show only the given names by removing all other names from the given collection of defined
+   * names.
+   * @param definedNames the names that were defined before this operation
+   * @param shownNames the names to be shown
+   */
+  Map<String, Element> show(Map<String, Element> definedNames, List<String> shownNames) {
+    Map<String, Element> newNames = new Map<String, Element>();
+    for (String name in shownNames) {
+      Element element = definedNames[name];
+      if (element != null) {
+        newNames[name] = element;
+      }
+    }
+    return newNames;
+  }
+}
+/**
+ * The abstract class {@code Scope} defines the behavior common to name scopes used by the resolver
+ * to determine which names are visible at any given point in the code.
+ */
+abstract class Scope {
+  /**
+   * The prefix used to mark an identifier as being private to its library.
+   */
+  static String PRIVATE_NAME_PREFIX = "_";
+  /**
+   * The suffix added to the declared name of a setter when looking up the setter. Used to
+   * disambiguate between a getter and a setter that have the same name.
+   */
+  static String SETTER_SUFFIX = "=";
+  /**
+   * The name used to look up the method used to implement the unary minus operator. Used to
+   * disambiguate between the unary and binary operators.
+   */
+  static String UNARY_MINUS = "unary-";
+  /**
+   * Return {@code true} if the given name is a library-private name.
+   * @param name the name being tested
+   * @return {@code true} if the given name is a library-private name
+   */
+  static bool isPrivateName(String name) => name != null && name.startsWith(PRIVATE_NAME_PREFIX);
+  /**
+   * A table mapping names that are defined in this scope to the element representing the thing
+   * declared with that name.
+   */
+  Map<String, Element> _definedNames = new Map<String, Element>();
+  /**
+   * Initialize a newly created scope to be empty.
+   */
+  Scope() : super() {
+  }
+  /**
+   * Add the given element to this scope. If there is already an element with the given name defined
+   * in this scope, then an error will be generated and the original element will continue to be
+   * mapped to the name. If there is an element with the given name in an enclosing scope, then a
+   * warning will be generated but the given element will hide the inherited element.
+   * @param element the element to be added to this scope
+   */
+  void define(Element element) {
+    String name = getName(element);
+    if (_definedNames.containsKey(name)) {
+      errorListener.onError(getErrorForDuplicate(_definedNames[name], element));
+    } else {
+      Element overriddenElement = lookup3(name, definingLibrary);
+      if (overriddenElement != null) {
+        AnalysisError error = getErrorForHiding(overriddenElement, element);
+        if (error != null) {
+          errorListener.onError(error);
+        }
+      }
+      _definedNames[name] = element;
+    }
+  }
+  /**
+   * Return the element with which the given identifier is associated, or {@code null} if the name
+   * is not defined within this scope.
+   * @param identifier the identifier associated with the element to be returned
+   * @param referencingLibrary the library that contains the reference to the name, used to
+   * implement library-level privacy
+   * @return the element with which the given identifier is associated
+   */
+  Element lookup(Identifier identifier, LibraryElement referencingLibrary) => lookup3(identifier.name, referencingLibrary);
+  /**
+   * Add the given element to this scope without checking for duplication or hiding.
+   * @param element the element to be added to this scope
+   */
+  void defineWithoutChecking(Element element) {
+    _definedNames[getName(element)] = element;
+  }
+  /**
+   * Return the element representing the library in which this scope is enclosed.
+   * @return the element representing the library in which this scope is enclosed
+   */
+  LibraryElement get definingLibrary;
+  /**
+   * Return the error code to be used when reporting that a name being defined locally conflicts
+   * with another element of the same name in the local scope.
+   * @param existing the first element to be declared with the conflicting name
+   * @param duplicate another element declared with the conflicting name
+   * @return the error code used to report duplicate names within a scope
+   */
+  AnalysisError getErrorForDuplicate(Element existing, Element duplicate) => new AnalysisError.con1(source, ResolverErrorCode.DUPLICATE_MEMBER_ERROR, [existing.name]);
+  /**
+   * Return the error code to be used when reporting that a name being defined locally hides a name
+   * defined in an outer scope.
+   * @param hidden the element whose visibility is being hidden
+   * @param hiding the element that is hiding the visibility of another declaration
+   * @return the error code used to report name hiding
+   */
+  AnalysisError getErrorForHiding(Element hidden, Element hiding) => new AnalysisError.con1(source, ResolverErrorCode.DUPLICATE_MEMBER_WARNING, [hidden.name]);
+  /**
+   * Return the listener that is to be informed when an error is encountered.
+   * @return the listener that is to be informed when an error is encountered
+   */
+  AnalysisErrorListener get errorListener;
+  /**
+   * Return the source object representing the compilation unit with which errors related to this
+   * scope should be associated.
+   * @return the source object with which errors should be associated
+   */
+  Source get source => definingLibrary.definingCompilationUnit.source;
+  /**
+   * Return the element with which the given name is associated, or {@code null} if the name is not
+   * defined within this scope. This method only returns elements that are directly defined within
+   * this scope, not elements that are defined in an enclosing scope.
+   * @param name the name associated with the element to be returned
+   * @param referencingLibrary the library that contains the reference to the name, used to
+   * implement library-level privacy
+   * @return the element with which the given name is associated
+   */
+  Element localLookup(String name, LibraryElement referencingLibrary) => _definedNames[name];
+  /**
+   * Return the element with which the given name is associated, or {@code null} if the name is not
+   * defined within this scope.
+   * @param name the name associated with the element to be returned
+   * @param referencingLibrary the library that contains the reference to the name, used to
+   * implement library-level privacy
+   * @return the element with which the given name is associated
+   */
+  Element lookup3(String name, LibraryElement referencingLibrary);
+  /**
+   * Return the name that will be used to look up the given element.
+   * @param element the element whose look-up name is to be returned
+   * @return the name that will be used to look up the given element
+   */
+  String getName(Element element) {
+    if (element is MethodElement) {
+      MethodElement method = (element as MethodElement);
+      if (method.name == "-" && method.parameters.length == 0) {
+        return UNARY_MINUS;
+      }
+    } else if (element is PropertyAccessorElement) {
+      PropertyAccessorElement accessor = (element as PropertyAccessorElement);
+      if (accessor.isSetter()) {
+        return "${accessor.name}${SETTER_SUFFIX}";
+      }
+    }
+    return element.name;
+  }
+}
+/**
+ * The enumeration {@code ResolverErrorCode} defines the error codes used for errors detected by the
+ * resolver. The convention for this class is for the name of the error code to indicate the problem
+ * that caused the error to be generated and for the error message to explain what is wrong and,
+ * when appropriate, how the problem can be corrected.
+ */
+class ResolverErrorCode implements ErrorCode {
+  static final ResolverErrorCode BREAK_LABEL_ON_SWITCH_MEMBER = new ResolverErrorCode('BREAK_LABEL_ON_SWITCH_MEMBER', 0, ErrorType.COMPILE_TIME_ERROR, "Break label resolves to case or default statement");
+  static final ResolverErrorCode CANNOT_BE_RESOLVED = new ResolverErrorCode('CANNOT_BE_RESOLVED', 1, ErrorType.STATIC_WARNING, "Cannot resolve the name '%s'");
+  static final ResolverErrorCode CONTINUE_LABEL_ON_SWITCH = new ResolverErrorCode('CONTINUE_LABEL_ON_SWITCH', 2, ErrorType.COMPILE_TIME_ERROR, "A continue label resolves to switch, must be loop or switch member");
+  /**
+   * It is a compile-time error if [the URI] is not a compile-time constant, or if [the URI]
+   * involves string interpolation.
+   */
+  static final ResolverErrorCode INVALID_URI = new ResolverErrorCode('INVALID_URI', 3, ErrorType.COMPILE_TIME_ERROR, "URI's used in directives must be compile time constants without interpolation expressions");
+  static final ResolverErrorCode LABEL_IN_OUTER_SCOPE = new ResolverErrorCode('LABEL_IN_OUTER_SCOPE', 4, ErrorType.COMPILE_TIME_ERROR, "Cannot reference label '%s' declared in an outer method or function");
+  static final ResolverErrorCode MISSING_LIBRARY_DIRECTIVE_IMPORTED = new ResolverErrorCode('MISSING_LIBRARY_DIRECTIVE_IMPORTED', 5, ErrorType.COMPILE_TIME_ERROR, "Libraries that are imported by other libraries must have a library directive");
+  static final ResolverErrorCode MISSING_LIBRARY_DIRECTIVE_WITH_PART = new ResolverErrorCode('MISSING_LIBRARY_DIRECTIVE_WITH_PART', 6, ErrorType.COMPILE_TIME_ERROR, "Libraries that have parts must have a library directive");
+  static final ResolverErrorCode MISSING_PART_OF_DIRECTIVE = new ResolverErrorCode('MISSING_PART_OF_DIRECTIVE', 7, ErrorType.COMPILE_TIME_ERROR, "The included part must have a part-of directive");
+  static final ResolverErrorCode NON_BOOLEAN_CONDITION = new ResolverErrorCode('NON_BOOLEAN_CONDITION', 8, ErrorType.STATIC_TYPE_WARNING, "Conditions must have a static type of 'bool'");
+  static final ResolverErrorCode PART_WITH_WRONG_LIBRARY_NAME = new ResolverErrorCode('PART_WITH_WRONG_LIBRARY_NAME', 9, ErrorType.STATIC_WARNING, "The included part appears to be part of the library '%s'");
+  static final ResolverErrorCode UNDEFINED_LABEL = new ResolverErrorCode('UNDEFINED_LABEL', 10, ErrorType.COMPILE_TIME_ERROR, "The label '%s' is not defined");
+  static final ResolverErrorCode DUPLICATE_MEMBER_ERROR = new ResolverErrorCode('DUPLICATE_MEMBER_ERROR', 11, ErrorType.COMPILE_TIME_ERROR, "Duplicate member '%s'");
+  static final ResolverErrorCode DUPLICATE_MEMBER_WARNING = new ResolverErrorCode('DUPLICATE_MEMBER_WARNING', 12, ErrorType.STATIC_WARNING, "Duplicate member '%s'");
+  static final List<ResolverErrorCode> values = [BREAK_LABEL_ON_SWITCH_MEMBER, CANNOT_BE_RESOLVED, CONTINUE_LABEL_ON_SWITCH, INVALID_URI, LABEL_IN_OUTER_SCOPE, MISSING_LIBRARY_DIRECTIVE_IMPORTED, MISSING_LIBRARY_DIRECTIVE_WITH_PART, MISSING_PART_OF_DIRECTIVE, NON_BOOLEAN_CONDITION, PART_WITH_WRONG_LIBRARY_NAME, UNDEFINED_LABEL, DUPLICATE_MEMBER_ERROR, DUPLICATE_MEMBER_WARNING];
+  final String __name;
+  final int __ordinal;
+  /**
+   * The type of this error.
+   */
+  ErrorType _type;
+  /**
+   * The message template used to create the message to be displayed for this error.
+   */
+  String _message;
+  /**
+   * Initialize a newly created error code to have the given type and message.
+   * @param type the type of this error
+   * @param message the message template used to create the message to be displayed for the error
+   */
+  ResolverErrorCode(this.__name, this.__ordinal, ErrorType type, String message) {
+    this._type = type;
+    this._message = message;
+  }
+  ErrorSeverity get errorSeverity => _type.severity;
+  String get message => _message;
+  ErrorType get type => _type;
+  bool needsRecompilation() => true;
+  String toString() => __name;
+}
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/lib/src/generated/scanner.dart b/pkg/analyzer-experimental/lib/src/generated/scanner.dart
index c01e672..5251003 100644
--- a/pkg/analyzer-experimental/lib/src/generated/scanner.dart
+++ b/pkg/analyzer-experimental/lib/src/generated/scanner.dart
@@ -92,10 +92,10 @@
    * @param syntax the lexeme for the keyword
    */
   Keyword.con1(String ___name, int ___ordinal, String syntax) {
-    _jtd_constructor_215_impl(___name, ___ordinal, syntax);
+    _jtd_constructor_224_impl(___name, ___ordinal, syntax);
   }
-  _jtd_constructor_215_impl(String ___name, int ___ordinal, String syntax) {
-    _jtd_constructor_216_impl(___name, ___ordinal, syntax, false);
+  _jtd_constructor_224_impl(String ___name, int ___ordinal, String syntax) {
+    _jtd_constructor_225_impl(___name, ___ordinal, syntax, false);
   }
   /**
    * Initialize a newly created keyword to have the given syntax. The keyword is a pseudo-keyword if
@@ -103,13 +103,13 @@
    * @param syntax the lexeme for the keyword
    * @param isPseudoKeyword {@code true} if this keyword is a pseudo-keyword
    */
-  Keyword.con2(String ___name, int ___ordinal, String syntax, bool isPseudoKeyword) {
-    _jtd_constructor_216_impl(___name, ___ordinal, syntax, isPseudoKeyword);
+  Keyword.con2(String ___name, int ___ordinal, String syntax2, bool isPseudoKeyword) {
+    _jtd_constructor_225_impl(___name, ___ordinal, syntax2, isPseudoKeyword);
   }
-  _jtd_constructor_216_impl(String ___name, int ___ordinal, String syntax, bool isPseudoKeyword) {
+  _jtd_constructor_225_impl(String ___name, int ___ordinal, String syntax2, bool isPseudoKeyword) {
     __name = ___name;
     __ordinal = ___ordinal;
-    this._syntax = syntax;
+    this._syntax = syntax2;
     this._isPseudoKeyword2 = isPseudoKeyword;
   }
   /**
@@ -288,7 +288,7 @@
    */
   Token setNext(Token token) {
     _next = token;
-    token.previous2 = this;
+    token.previous = this;
     return token;
   }
   /**
@@ -306,8 +306,8 @@
    * offset.
    * @param offset the offset from the beginning of the file to the first character in the token
    */
-  void set offset2(int offset) {
-    this._offset = offset;
+  void set offset(int offset3) {
+    this._offset = offset3;
   }
   String toString() => lexeme;
   /**
@@ -320,8 +320,8 @@
    * Set the previous token in the token stream to the given token.
    * @param previous the previous token in the token stream
    */
-  void set previous2(Token previous) {
-    this._previous = previous;
+  void set previous(Token previous2) {
+    this._previous = previous2;
   }
 }
 /**
@@ -510,19 +510,19 @@
    */
   String _lexeme;
   TokenType.con1(String ___name, int ___ordinal) {
-    _jtd_constructor_227_impl(___name, ___ordinal);
+    _jtd_constructor_236_impl(___name, ___ordinal);
   }
-  _jtd_constructor_227_impl(String ___name, int ___ordinal) {
-    _jtd_constructor_228_impl(___name, ___ordinal, TokenClass.NO_CLASS, null);
+  _jtd_constructor_236_impl(String ___name, int ___ordinal) {
+    _jtd_constructor_237_impl(___name, ___ordinal, TokenClass.NO_CLASS, null);
   }
-  TokenType.con2(String ___name, int ___ordinal, TokenClass tokenClass, String lexeme) {
-    _jtd_constructor_228_impl(___name, ___ordinal, tokenClass, lexeme);
+  TokenType.con2(String ___name, int ___ordinal, TokenClass tokenClass2, String lexeme2) {
+    _jtd_constructor_237_impl(___name, ___ordinal, tokenClass2, lexeme2);
   }
-  _jtd_constructor_228_impl(String ___name, int ___ordinal, TokenClass tokenClass, String lexeme) {
+  _jtd_constructor_237_impl(String ___name, int ___ordinal, TokenClass tokenClass2, String lexeme2) {
     __name = ___name;
     __ordinal = ___ordinal;
-    this._tokenClass = tokenClass == null ? TokenClass.NO_CLASS : tokenClass;
-    this._lexeme = lexeme;
+    this._tokenClass = tokenClass2 == null ? TokenClass.NO_CLASS : tokenClass2;
+    this._lexeme = lexeme2;
   }
   /**
    * Return the lexeme that defines this type of token, or {@code null} if there is more than one
@@ -539,57 +539,68 @@
    * Return {@code true} if this type of token represents an additive operator.
    * @return {@code true} if this type of token represents an additive operator
    */
-  bool isAdditiveOperator() => _tokenClass == TokenClass.ADDITIVE_OPERATOR;
+  bool isAdditiveOperator() => identical(_tokenClass, TokenClass.ADDITIVE_OPERATOR);
   /**
    * Return {@code true} if this type of token represents an assignment operator.
    * @return {@code true} if this type of token represents an assignment operator
    */
-  bool isAssignmentOperator() => _tokenClass == TokenClass.ASSIGNMENT_OPERATOR;
+  bool isAssignmentOperator() => identical(_tokenClass, TokenClass.ASSIGNMENT_OPERATOR);
+  /**
+   * Return {@code true} if this type of token represents an associative operator. An associative
+   * operator is an operator for which the following equality is true:{@code (a * b) * c == a * (b * c)}. In other words, if the result of applying the operator to
+   * multiple operands does not depend on the order in which those applications occur.
+   * <p>
+   * Note: This method considers the logical-and and logical-or operators to be associative, even
+   * though the order in which the application of those operators can have an effect because
+   * evaluation of the right-hand operand is conditional.
+   * @return {@code true} if this type of token represents an associative operator
+   */
+  bool isAssociativeOperator() => identical(this, AMPERSAND) || identical(this, AMPERSAND_AMPERSAND) || identical(this, BAR) || identical(this, BAR_BAR) || identical(this, CARET) || identical(this, PLUS) || identical(this, STAR);
   /**
    * Return {@code true} if this type of token represents an equality operator.
    * @return {@code true} if this type of token represents an equality operator
    */
-  bool isEqualityOperator() => _tokenClass == TokenClass.EQUALITY_OPERATOR;
+  bool isEqualityOperator() => identical(_tokenClass, TokenClass.EQUALITY_OPERATOR);
   /**
    * Return {@code true} if this type of token represents an increment operator.
    * @return {@code true} if this type of token represents an increment operator
    */
-  bool isIncrementOperator() => _lexeme == "++" || _lexeme == "--";
+  bool isIncrementOperator() => identical(_lexeme, "++") || identical(_lexeme, "--");
   /**
    * Return {@code true} if this type of token represents a multiplicative operator.
    * @return {@code true} if this type of token represents a multiplicative operator
    */
-  bool isMultiplicativeOperator() => _tokenClass == TokenClass.MULTIPLICATIVE_OPERATOR;
+  bool isMultiplicativeOperator() => identical(_tokenClass, TokenClass.MULTIPLICATIVE_OPERATOR);
   /**
    * Return {@code true} if this token type represents an operator.
    * @return {@code true} if this token type represents an operator
    */
-  bool isOperator() => _tokenClass != TokenClass.NO_CLASS && this != TokenType.OPEN_PAREN && this != TokenType.OPEN_SQUARE_BRACKET && this != TokenType.PERIOD;
+  bool isOperator() => _tokenClass != TokenClass.NO_CLASS && this != OPEN_PAREN && this != OPEN_SQUARE_BRACKET && this != PERIOD;
   /**
    * Return {@code true} if this type of token represents a relational operator.
    * @return {@code true} if this type of token represents a relational operator
    */
-  bool isRelationalOperator() => _tokenClass == TokenClass.RELATIONAL_OPERATOR;
+  bool isRelationalOperator() => identical(_tokenClass, TokenClass.RELATIONAL_OPERATOR);
   /**
    * Return {@code true} if this type of token represents a shift operator.
    * @return {@code true} if this type of token represents a shift operator
    */
-  bool isShiftOperator() => _tokenClass == TokenClass.SHIFT_OPERATOR;
+  bool isShiftOperator() => identical(_tokenClass, TokenClass.SHIFT_OPERATOR);
   /**
    * Return {@code true} if this type of token represents a unary postfix operator.
    * @return {@code true} if this type of token represents a unary postfix operator
    */
-  bool isUnaryPostfixOperator() => _tokenClass == TokenClass.UNARY_POSTFIX_OPERATOR;
+  bool isUnaryPostfixOperator() => identical(_tokenClass, TokenClass.UNARY_POSTFIX_OPERATOR);
   /**
    * Return {@code true} if this type of token represents a unary prefix operator.
    * @return {@code true} if this type of token represents a unary prefix operator
    */
-  bool isUnaryPrefixOperator() => _tokenClass == TokenClass.UNARY_PREFIX_OPERATOR;
+  bool isUnaryPrefixOperator() => identical(_tokenClass, TokenClass.UNARY_PREFIX_OPERATOR);
   /**
    * Return {@code true} if this token type represents an operator that can be defined by users.
    * @return {@code true} if this token type represents an operator that can be defined by users
    */
-  bool isUserDefinableOperator() => _lexeme == "==" || _lexeme == "~" || _lexeme == "[]" || _lexeme == "[]=" || _lexeme == "*" || _lexeme == "/" || _lexeme == "%" || _lexeme == "~/" || _lexeme == "+" || _lexeme == "-" || _lexeme == "<<" || _lexeme == ">>" || _lexeme == ">=" || _lexeme == ">" || _lexeme == "<=" || _lexeme == "<" || _lexeme == "&" || _lexeme == "^" || _lexeme == "|";
+  bool isUserDefinableOperator() => identical(_lexeme, "==") || identical(_lexeme, "~") || identical(_lexeme, "[]") || identical(_lexeme, "[]=") || identical(_lexeme, "*") || identical(_lexeme, "/") || identical(_lexeme, "%") || identical(_lexeme, "~/") || identical(_lexeme, "+") || identical(_lexeme, "-") || identical(_lexeme, "<<") || identical(_lexeme, ">>") || identical(_lexeme, ">=") || identical(_lexeme, ">") || identical(_lexeme, "<=") || identical(_lexeme, "<") || identical(_lexeme, "&") || identical(_lexeme, "^") || identical(_lexeme, "|");
   String toString() => __name;
 }
 class TokenType_EOF extends TokenType {
@@ -632,7 +643,7 @@
    * @param offset the offset from the beginning of the file to the first character in the token
    */
   BeginToken(TokenType type, int offset) : super(type, offset) {
-    assert((type == TokenType.OPEN_CURLY_BRACKET || type == TokenType.OPEN_PAREN || type == TokenType.OPEN_SQUARE_BRACKET || type == TokenType.STRING_INTERPOLATION_EXPRESSION));
+    assert((identical(type, TokenType.OPEN_CURLY_BRACKET) || identical(type, TokenType.OPEN_PAREN) || identical(type, TokenType.OPEN_SQUARE_BRACKET) || identical(type, TokenType.STRING_INTERPOLATION_EXPRESSION)));
   }
   /**
    * Return the token that corresponds to this token.
@@ -643,7 +654,7 @@
    * Set the token that corresponds to this token to the given token.
    * @param token the token that corresponds to this token
    */
-  void set endToken2(Token token) {
+  void set endToken(Token token) {
     this._endToken = token;
   }
 }
@@ -724,18 +735,18 @@
    */
   int _precedence = 0;
   TokenClass.con1(String ___name, int ___ordinal) {
-    _jtd_constructor_225_impl(___name, ___ordinal);
+    _jtd_constructor_234_impl(___name, ___ordinal);
   }
-  _jtd_constructor_225_impl(String ___name, int ___ordinal) {
-    _jtd_constructor_226_impl(___name, ___ordinal, 0);
+  _jtd_constructor_234_impl(String ___name, int ___ordinal) {
+    _jtd_constructor_235_impl(___name, ___ordinal, 0);
   }
-  TokenClass.con2(String ___name, int ___ordinal, int precedence) {
-    _jtd_constructor_226_impl(___name, ___ordinal, precedence);
+  TokenClass.con2(String ___name, int ___ordinal, int precedence2) {
+    _jtd_constructor_235_impl(___name, ___ordinal, precedence2);
   }
-  _jtd_constructor_226_impl(String ___name, int ___ordinal, int precedence) {
+  _jtd_constructor_235_impl(String ___name, int ___ordinal, int precedence2) {
     __name = ___name;
     __ordinal = ___ordinal;
-    this._precedence = precedence;
+    this._precedence = precedence2;
   }
   /**
    * Return the precedence of tokens of this class, or {@code 0} if the such tokens do not represent
@@ -807,14 +818,14 @@
     if (_charOffset + 1 >= _stringLength) {
       return -1;
     }
-    return _string.charCodeAt(++_charOffset);
+    return _string.codeUnitAt(++_charOffset);
   }
   String getString(int start, int endDelta) => _string.substring(start - _offsetDelta, _charOffset + 1 + endDelta);
   int peek() {
     if (_charOffset + 1 >= _string.length) {
       return -1;
     }
-    return _string.charCodeAt(_charOffset + 1);
+    return _string.codeUnitAt(_charOffset + 1);
   }
 }
 /**
@@ -965,12 +976,12 @@
       _lastComment = _lastComment.setNext(new StringToken(type, value, _tokenStart));
     }
   }
-  void appendEndToken(TokenType type, TokenType beginType) {
+  void appendEndToken(TokenType type26, TokenType beginType) {
     Token token;
     if (_firstComment == null) {
-      token = new Token(type, _tokenStart);
+      token = new Token(type26, _tokenStart);
     } else {
-      token = new TokenWithComment(type, _tokenStart, _firstComment);
+      token = new TokenWithComment(type26, _tokenStart, _firstComment);
       _firstComment = null;
       _lastComment = null;
     }
@@ -978,8 +989,8 @@
     int last = _groupingStack.length - 1;
     if (last >= 0) {
       BeginToken begin = _groupingStack[last];
-      if (begin.type == beginType) {
-        begin.endToken2 = token;
+      if (identical(begin.type, beginType)) {
+        begin.endToken = token;
         _groupingStack.removeAt(last);
       }
     }
@@ -1049,14 +1060,14 @@
   }
   int bigSwitch(int next) {
     beginToken();
-    if (next == 0xd) {
+    if (next == 0xD) {
       next = advance();
-      if (next == 0xa) {
+      if (next == 0xA) {
         next = advance();
       }
       recordStartOfLine();
       return next;
-    } else if (next == 0xa) {
+    } else if (next == 0xA) {
       recordStartOfLine();
       return advance();
     } else if (next == 0x9 || next == 0x20) {
@@ -1069,31 +1080,31 @@
         return tokenizeString(advance(), start, true);
       }
     }
-    if (0x61 <= next && next <= 0x7a) {
+    if (0x61 <= next && next <= 0x7A) {
       return tokenizeKeywordOrIdentifier(next, true);
     }
-    if ((0x41 <= next && next <= 0x5a) || next == 0x5f || next == 0x24) {
+    if ((0x41 <= next && next <= 0x5A) || next == 0x5F || next == 0x24) {
       return tokenizeIdentifier(next, offset, true);
     }
-    if (next == 0x3c) {
+    if (next == 0x3C) {
       return tokenizeLessThan(next);
     }
-    if (next == 0x3e) {
+    if (next == 0x3E) {
       return tokenizeGreaterThan(next);
     }
-    if (next == 0x3d) {
+    if (next == 0x3D) {
       return tokenizeEquals(next);
     }
     if (next == 0x21) {
       return tokenizeExclamation(next);
     }
-    if (next == 0x2b) {
+    if (next == 0x2B) {
       return tokenizePlus(next);
     }
-    if (next == 0x2d) {
+    if (next == 0x2D) {
       return tokenizeMinus(next);
     }
-    if (next == 0x2a) {
+    if (next == 0x2A) {
       return tokenizeMultiply(next);
     }
     if (next == 0x25) {
@@ -1102,19 +1113,19 @@
     if (next == 0x26) {
       return tokenizeAmpersand(next);
     }
-    if (next == 0x7c) {
+    if (next == 0x7C) {
       return tokenizeBar(next);
     }
-    if (next == 0x5e) {
+    if (next == 0x5E) {
       return tokenizeCaret(next);
     }
-    if (next == 0x5b) {
+    if (next == 0x5B) {
       return tokenizeOpenSquareBracket(next);
     }
-    if (next == 0x7e) {
+    if (next == 0x7E) {
       return tokenizeTilde(next);
     }
-    if (next == 0x5c) {
+    if (next == 0x5C) {
       appendToken(TokenType.BACKSLASH);
       return advance();
     }
@@ -1129,23 +1140,23 @@
       appendEndToken(TokenType.CLOSE_PAREN, TokenType.OPEN_PAREN);
       return advance();
     }
-    if (next == 0x2c) {
+    if (next == 0x2C) {
       appendToken(TokenType.COMMA);
       return advance();
     }
-    if (next == 0x3a) {
+    if (next == 0x3A) {
       appendToken(TokenType.COLON);
       return advance();
     }
-    if (next == 0x3b) {
+    if (next == 0x3B) {
       appendToken(TokenType.SEMICOLON);
       return advance();
     }
-    if (next == 0x3f) {
+    if (next == 0x3F) {
       appendToken(TokenType.QUESTION);
       return advance();
     }
-    if (next == 0x5d) {
+    if (next == 0x5D) {
       appendEndToken(TokenType.CLOSE_SQUARE_BRACKET, TokenType.OPEN_SQUARE_BRACKET);
       return advance();
     }
@@ -1153,15 +1164,15 @@
       appendToken(TokenType.BACKPING);
       return advance();
     }
-    if (next == 0x7b) {
+    if (next == 0x7B) {
       appendBeginToken(TokenType.OPEN_CURLY_BRACKET);
       return advance();
     }
-    if (next == 0x7d) {
+    if (next == 0x7D) {
       appendEndToken(TokenType.CLOSE_CURLY_BRACKET, TokenType.OPEN_CURLY_BRACKET);
       return advance();
     }
-    if (next == 0x2f) {
+    if (next == 0x2F) {
       return tokenizeSlashOrComment(next);
     }
     if (next == 0x40) {
@@ -1171,7 +1182,7 @@
     if (next == 0x22 || next == 0x27) {
       return tokenizeString(next, offset, false);
     }
-    if (next == 0x2e) {
+    if (next == 0x2E) {
       return tokenizeDotOrNumber(next);
     }
     if (next == 0x30) {
@@ -1186,7 +1197,7 @@
     if (Character.isLetter(next)) {
       return tokenizeIdentifier(next, offset, true);
     }
-    if (next == AbstractScanner._$NBSP) {
+    if (next == _$NBSP) {
       return advance();
     }
     reportError(ScannerErrorCode.ILLEGAL_CHARACTER, [next]);
@@ -1202,7 +1213,7 @@
     int last = _groupingStack.length - 1;
     while (last >= 0) {
       BeginToken begin = _groupingStack[last];
-      if (begin.type == TokenType.OPEN_CURLY_BRACKET || begin.type == TokenType.STRING_INTERPOLATION_EXPRESSION) {
+      if (identical(begin.type, TokenType.OPEN_CURLY_BRACKET) || identical(begin.type, TokenType.STRING_INTERPOLATION_EXPRESSION)) {
         return begin;
       }
       _hasUnmatchedGroups2 = true;
@@ -1250,7 +1261,7 @@
     if (next == 0x26) {
       appendToken(TokenType.AMPERSAND_AMPERSAND);
       return advance();
-    } else if (next == 0x3d) {
+    } else if (next == 0x3D) {
       appendToken(TokenType.AMPERSAND_EQ);
       return advance();
     } else {
@@ -1260,10 +1271,10 @@
   }
   int tokenizeBar(int next) {
     next = advance();
-    if (next == 0x7c) {
+    if (next == 0x7C) {
       appendToken(TokenType.BAR_BAR);
       return advance();
-    } else if (next == 0x3d) {
+    } else if (next == 0x3D) {
       appendToken(TokenType.BAR_EQ);
       return advance();
     } else {
@@ -1271,14 +1282,14 @@
       return next;
     }
   }
-  int tokenizeCaret(int next) => select(0x3d, TokenType.CARET_EQ, TokenType.CARET);
+  int tokenizeCaret(int next) => select(0x3D, TokenType.CARET_EQ, TokenType.CARET);
   int tokenizeDotOrNumber(int next) {
     int start = offset;
     next = advance();
     if ((0x30 <= next && next <= 0x39)) {
       return tokenizeFractionPart(next, start);
-    } else if (0x2e == next) {
-      return select(0x2e, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD);
+    } else if (0x2E == next) {
+      return select(0x2E, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD);
     } else {
       appendToken(TokenType.PERIOD);
       return next;
@@ -1286,10 +1297,10 @@
   }
   int tokenizeEquals(int next) {
     next = advance();
-    if (next == 0x3d) {
+    if (next == 0x3D) {
       appendToken(TokenType.EQ_EQ);
       return advance();
-    } else if (next == 0x3e) {
+    } else if (next == 0x3E) {
       appendToken(TokenType.FUNCTION);
       return advance();
     }
@@ -1298,7 +1309,7 @@
   }
   int tokenizeExclamation(int next) {
     next = advance();
-    if (next == 0x3d) {
+    if (next == 0x3D) {
       appendToken(TokenType.BANG_EQ);
       return advance();
     }
@@ -1306,7 +1317,7 @@
     return next;
   }
   int tokenizeExponent(int next) {
-    if (next == 0x2b || next == 0x2d) {
+    if (next == 0x2B || next == 0x2D) {
       next = advance();
     }
     bool hasDigits = false;
@@ -1341,8 +1352,8 @@
     }
     if (!hasDigit) {
       appendStringToken(TokenType.INT, getString(start, -2));
-      if (0x2e == next) {
-        return select2(0x2e, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD, offset - 1);
+      if (0x2E == next) {
+        return select2(0x2E, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD, offset - 1);
       }
       appendToken2(TokenType.PERIOD, offset - 1);
       return bigSwitch(next);
@@ -1355,12 +1366,12 @@
   }
   int tokenizeGreaterThan(int next) {
     next = advance();
-    if (0x3d == next) {
+    if (0x3D == next) {
       appendToken(TokenType.GT_EQ);
       return advance();
-    } else if (0x3e == next) {
+    } else if (0x3E == next) {
       next = advance();
-      if (0x3d == next) {
+      if (0x3D == next) {
         appendToken(TokenType.GT_GT_EQ);
         return advance();
       } else {
@@ -1397,7 +1408,7 @@
     return tokenizeNumber(next);
   }
   int tokenizeIdentifier(int next, int start, bool allowDollar) {
-    while ((0x61 <= next && next <= 0x7a) || (0x41 <= next && next <= 0x5a) || (0x30 <= next && next <= 0x39) || next == 0x5f || (next == 0x24 && allowDollar) || Character.isLetterOrDigit(next)) {
+    while ((0x61 <= next && next <= 0x7A) || (0x41 <= next && next <= 0x5A) || (0x30 <= next && next <= 0x39) || next == 0x5F || (next == 0x24 && allowDollar) || Character.isLetterOrDigit(next)) {
       next = advance();
     }
     appendStringToken(TokenType.IDENTIFIER, getString(start, next < 0 ? 0 : -1));
@@ -1407,7 +1418,7 @@
     appendBeginToken(TokenType.STRING_INTERPOLATION_EXPRESSION);
     next = advance();
     while (next != -1) {
-      if (next == 0x7d) {
+      if (next == 0x7D) {
         BeginToken begin = findTokenMatchingClosingBraceInInterpolationExpression();
         if (begin == null) {
           beginToken();
@@ -1415,12 +1426,12 @@
           next = advance();
           beginToken();
           return next;
-        } else if (begin.type == TokenType.OPEN_CURLY_BRACKET) {
+        } else if (identical(begin.type, TokenType.OPEN_CURLY_BRACKET)) {
           beginToken();
           appendEndToken(TokenType.CLOSE_CURLY_BRACKET, TokenType.OPEN_CURLY_BRACKET);
           next = advance();
           beginToken();
-        } else if (begin.type == TokenType.STRING_INTERPOLATION_EXPRESSION) {
+        } else if (identical(begin.type, TokenType.STRING_INTERPOLATION_EXPRESSION)) {
           beginToken();
           appendEndToken(TokenType.CLOSE_CURLY_BRACKET, TokenType.STRING_INTERPOLATION_EXPRESSION);
           next = advance();
@@ -1445,32 +1456,32 @@
     beginToken();
     return next;
   }
-  int tokenizeKeywordOrIdentifier(int next, bool allowDollar) {
+  int tokenizeKeywordOrIdentifier(int next2, bool allowDollar) {
     KeywordState state = KeywordState.KEYWORD_STATE;
     int start = offset;
-    while (state != null && 0x61 <= next && next <= 0x7a) {
-      state = state.next(next as int);
-      next = advance();
+    while (state != null && 0x61 <= next2 && next2 <= 0x7A) {
+      state = state.next((next2 as int));
+      next2 = advance();
     }
     if (state == null || state.keyword() == null) {
-      return tokenizeIdentifier(next, start, allowDollar);
+      return tokenizeIdentifier(next2, start, allowDollar);
     }
-    if ((0x41 <= next && next <= 0x5a) || (0x30 <= next && next <= 0x39) || next == 0x5f || next == 0x24) {
-      return tokenizeIdentifier(next, start, allowDollar);
-    } else if (next < 128) {
+    if ((0x41 <= next2 && next2 <= 0x5A) || (0x30 <= next2 && next2 <= 0x39) || next2 == 0x5F || next2 == 0x24) {
+      return tokenizeIdentifier(next2, start, allowDollar);
+    } else if (next2 < 128) {
       appendKeywordToken(state.keyword());
-      return next;
+      return next2;
     } else {
-      return tokenizeIdentifier(next, start, allowDollar);
+      return tokenizeIdentifier(next2, start, allowDollar);
     }
   }
   int tokenizeLessThan(int next) {
     next = advance();
-    if (0x3d == next) {
+    if (0x3D == next) {
       appendToken(TokenType.LT_EQ);
       return advance();
-    } else if (0x3c == next) {
-      return select(0x3d, TokenType.LT_LT_EQ, TokenType.LT_LT);
+    } else if (0x3C == next) {
+      return select(0x3D, TokenType.LT_LT_EQ, TokenType.LT_LT);
     } else {
       appendToken(TokenType.LT);
       return next;
@@ -1478,10 +1489,10 @@
   }
   int tokenizeMinus(int next) {
     next = advance();
-    if (next == 0x2d) {
+    if (next == 0x2D) {
       appendToken(TokenType.MINUS_MINUS);
       return advance();
-    } else if (next == 0x3d) {
+    } else if (next == 0x3D) {
       appendToken(TokenType.MINUS_EQ);
       return advance();
     } else {
@@ -1497,9 +1508,9 @@
         reportError(ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT, []);
         appendCommentToken(TokenType.MULTI_LINE_COMMENT, getString(_tokenStart, 0));
         return next;
-      } else if (0x2a == next) {
+      } else if (0x2A == next) {
         next = advance();
-        if (0x2f == next) {
+        if (0x2F == next) {
           --nesting;
           if (0 == nesting) {
             appendCommentToken(TokenType.MULTI_LINE_COMMENT, getString(_tokenStart, 0));
@@ -1508,9 +1519,9 @@
             next = advance();
           }
         }
-      } else if (0x2f == next) {
+      } else if (0x2F == next) {
         next = advance();
-        if (0x2a == next) {
+        if (0x2A == next) {
           next = advance();
           ++nesting;
         }
@@ -1565,7 +1576,7 @@
         }
         continue;
       }
-      if (next == 0x5c) {
+      if (next == 0x5C) {
         next = advance();
         if (next == -1) {
           break;
@@ -1577,14 +1588,14 @@
     appendStringToken(TokenType.STRING, getString(start, 0));
     return advance();
   }
-  int tokenizeMultiply(int next) => select(0x3d, TokenType.STAR_EQ, TokenType.STAR);
+  int tokenizeMultiply(int next) => select(0x3D, TokenType.STAR_EQ, TokenType.STAR);
   int tokenizeNumber(int next) {
     int start = offset;
     while (true) {
       next = advance();
       if (0x30 <= next && next <= 0x39) {
         continue;
-      } else if (next == 0x2e) {
+      } else if (next == 0x2E) {
         return tokenizeFractionPart(advance(), start);
       } else if (next == 0x64 || next == 0x44) {
         appendStringToken(TokenType.DOUBLE, getString(start, 0));
@@ -1599,20 +1610,20 @@
   }
   int tokenizeOpenSquareBracket(int next) {
     next = advance();
-    if (next == 0x5d) {
-      return select(0x3d, TokenType.INDEX_EQ, TokenType.INDEX);
+    if (next == 0x5D) {
+      return select(0x3D, TokenType.INDEX_EQ, TokenType.INDEX);
     } else {
       appendBeginToken(TokenType.OPEN_SQUARE_BRACKET);
       return next;
     }
   }
-  int tokenizePercent(int next) => select(0x3d, TokenType.PERCENT_EQ, TokenType.PERCENT);
+  int tokenizePercent(int next) => select(0x3D, TokenType.PERCENT_EQ, TokenType.PERCENT);
   int tokenizePlus(int next) {
     next = advance();
-    if (0x2b == next) {
+    if (0x2B == next) {
       appendToken(TokenType.PLUS_PLUS);
       return advance();
-    } else if (0x3d == next) {
+    } else if (0x3D == next) {
       appendToken(TokenType.PLUS_EQ);
       return advance();
     } else {
@@ -1623,7 +1634,7 @@
   int tokenizeSingleLineComment(int next) {
     while (true) {
       next = advance();
-      if (0xa == next || 0xd == next || -1 == next) {
+      if (0xA == next || 0xD == next || -1 == next) {
         appendCommentToken(TokenType.SINGLE_LINE_COMMENT, getString(_tokenStart, 0));
         return next;
       }
@@ -1635,7 +1646,7 @@
       if (next == quoteChar) {
         appendStringToken(TokenType.STRING, getString(start, 0));
         return advance();
-      } else if (next == 0xd || next == 0xa) {
+      } else if (next == 0xD || next == 0xA) {
         reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
         appendStringToken(TokenType.STRING, getString(start, 0));
         return advance();
@@ -1648,7 +1659,7 @@
   }
   int tokenizeSingleLineString(int next, int quoteChar, int start) {
     while (next != quoteChar) {
-      if (next == 0x5c) {
+      if (next == 0x5C) {
         next = advance();
       } else if (next == 0x24) {
         appendStringToken(TokenType.STRING, getString(start, -1));
@@ -1657,7 +1668,7 @@
         start = offset;
         continue;
       }
-      if (next <= 0xd && (next == 0xa || next == 0xd || next == -1)) {
+      if (next <= 0xD && (next == 0xA || next == 0xD || next == -1)) {
         reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
         appendStringToken(TokenType.STRING, getString(start, 0));
         return advance();
@@ -1669,11 +1680,11 @@
   }
   int tokenizeSlashOrComment(int next) {
     next = advance();
-    if (0x2a == next) {
+    if (0x2A == next) {
       return tokenizeMultiLineComment(next);
-    } else if (0x2f == next) {
+    } else if (0x2F == next) {
       return tokenizeSingleLineComment(next);
-    } else if (0x3d == next) {
+    } else if (0x3D == next) {
       appendToken(TokenType.SLASH_EQ);
       return advance();
     } else {
@@ -1702,7 +1713,7 @@
   int tokenizeStringInterpolation(int start) {
     beginToken();
     int next = advance();
-    if (next == 0x7b) {
+    if (next == 0x7B) {
       return tokenizeInterpolatedExpression(next, start);
     } else {
       return tokenizeInterpolatedIdentifier(next, start);
@@ -1713,7 +1724,7 @@
       if (peek() == 0x21) {
         do {
           next = advance();
-        } while (next != 0xa && next != 0xd && next > 0);
+        } while (next != 0xA && next != 0xD && next > 0);
         appendStringToken(TokenType.SCRIPT_TAG, getString(_tokenStart, 0));
         return next;
       }
@@ -1723,8 +1734,8 @@
   }
   int tokenizeTilde(int next) {
     next = advance();
-    if (next == 0x2f) {
-      return select(0x3d, TokenType.TILDE_SLASH_EQ, TokenType.TILDE_SLASH);
+    if (next == 0x2F) {
+      return select(0x3D, TokenType.TILDE_SLASH_EQ, TokenType.TILDE_SLASH);
     } else {
       appendToken(TokenType.TILDE);
       return next;
@@ -1777,18 +1788,18 @@
    * @param length the number of strings in the array that pass through the state being built
    * @return the state that was created
    */
-  static KeywordState computeKeywordStateTable(int start, List<String> strings, int offset, int length) {
+  static KeywordState computeKeywordStateTable(int start, List<String> strings, int offset, int length12) {
     List<KeywordState> result = new List<KeywordState>.fixedLength(26);
-    assert(length != 0);
+    assert(length12 != 0);
     int chunk = 0x0;
     int chunkStart = -1;
     bool isLeaf = false;
-    for (int i = offset; i < offset + length; i++) {
+    for (int i = offset; i < offset + length12; i++) {
       if (strings[i].length == start) {
         isLeaf = true;
       }
       if (strings[i].length > start) {
-        int c = strings[i].charCodeAt(start);
+        int c = strings[i].codeUnitAt(start);
         if (chunk != c) {
           if (chunkStart != -1) {
             result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkStart, i - chunkStart);
@@ -1800,9 +1811,9 @@
     }
     if (chunkStart != -1) {
       assert(result[chunk - 0x61] == null);
-      result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkStart, offset + length - chunkStart);
+      result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkStart, offset + length12 - chunkStart);
     } else {
-      assert(length == 1);
+      assert(length12 == 1);
       return new KeywordState(_EMPTY_TABLE, strings[offset]);
     }
     if (isLeaf) {
diff --git a/pkg/analyzer-experimental/lib/src/generated/sdk.dart b/pkg/analyzer-experimental/lib/src/generated/sdk.dart
new file mode 100644
index 0000000..de9c3de
--- /dev/null
+++ b/pkg/analyzer-experimental/lib/src/generated/sdk.dart
@@ -0,0 +1,662 @@
+// This code was auto-generated, is not intended to be edited, and is subject to
+// significant change. Please see the README file for more information.
+
+library engine.sdk;
+
+import 'dart:io';
+import 'dart:uri';
+import 'java_core.dart';
+import 'java_engine.dart';
+import 'package:analyzer-experimental/src/generated/source.dart';
+import 'package:analyzer-experimental/src/generated/error.dart';
+import 'package:analyzer-experimental/src/generated/scanner.dart';
+import 'package:analyzer-experimental/src/generated/parser.dart';
+import 'package:analyzer-experimental/src/generated/ast.dart';
+import 'package:analyzer-experimental/src/generated/engine.dart' show AnalysisEngine;
+
+/**
+ * Represents a single library in the SDK
+ */
+abstract class SdkLibrary {
+  /**
+   * Return the name of the category containing the library.
+   * @return the name of the category containing the library
+   */
+  String get category;
+  /**
+   * Return the path to the file defining the library. The path is relative to the {@code lib}directory within the SDK.
+   * @return the path to the file defining the library
+   */
+  String get path;
+  /**
+   * Return the short name of the library. This is the name used after {@code dart:} in a URI.
+   * @return the short name of the library
+   */
+  String get shortName;
+  /**
+   * Return {@code true} if this library can be compiled to JavaScript by dart2js.
+   * @return {@code true} if this library can be compiled to JavaScript by dart2js
+   */
+  bool isDart2JsLibrary();
+  /**
+   * Return {@code true} if the library is documented.
+   * @return {@code true} if the library is documented
+   */
+  bool isDocumented();
+  /**
+   * Return {@code true} if the library is an implementation library.
+   * @return {@code true} if the library is an implementation library
+   */
+  bool isImplementation();
+  /**
+   * Return {@code true} if library can be used for both client and server.
+   * @return {@code true} if this library can be used for both client and server.
+   */
+  bool isShared();
+  /**
+   * Return {@code true} if this library can be run on the VM.
+   * @return {@code true} if this library can be run on the VM
+   */
+  bool isVmLibrary();
+}
+/**
+ * Instances of the class {@code LibraryMap} map Dart library URI's to the {@link SdkLibraryImpllibrary}.
+ */
+class LibraryMap {
+  /**
+   * A table mapping Dart library URI's to the library.
+   */
+  Map<String, SdkLibraryImpl> _libraryMap = new Map<String, SdkLibraryImpl>();
+  /**
+   * Initialize a newly created library map to be empty.
+   */
+  LibraryMap() : super() {
+  }
+  /**
+   * Return the library with the given URI, or {@code null} if the URI does not map to a library.
+   * @param dartUri the URI of the library to be returned
+   * @return the library with the given URI
+   */
+  SdkLibrary getLibrary(String dartUri) => _libraryMap[dartUri];
+  /**
+   * Return an array containing all the sdk libraries {@link SdkLibraryImpl} in the mapping
+   * @return the sdk libraries in the mapping
+   */
+  List<SdkLibrary> get sdkLibraries => new List.from(_libraryMap.values);
+  /**
+   * Return an array containing the library URI's for which a mapping is available.
+   * @return the library URI's for which a mapping is available
+   */
+  List<String> get uris => new List.from(_libraryMap.keys.toSet());
+  /**
+   * Return the library with the given URI, or {@code null} if the URI does not map to a library.
+   * @param dartUri the URI of the library to be returned
+   * @param library the library with the given URI
+   */
+  void setLibrary(String dartUri, SdkLibraryImpl library) {
+    _libraryMap[dartUri] = library;
+  }
+  /**
+   * Return the number of library URI's for which a mapping is available.
+   * @return the number of library URI's for which a mapping is available
+   */
+  int size() => _libraryMap.length;
+}
+/**
+ * Instances of the class {@code DartSdk} represent a Dart SDK installed in a specified location.
+ */
+class DartSdk {
+  /**
+   * The short name of the dart SDK html library.
+   */
+  static String DART_HTML = "dart:html";
+  /**
+   * The directory containing the SDK.
+   */
+  File _sdkDirectory;
+  /**
+   * The revision number of this SDK, or {@code "0"} if the revision number cannot be discovered.
+   */
+  String _sdkVersion;
+  /**
+   * The file containing the Dartium executable.
+   */
+  File _dartiumExecutable;
+  /**
+   * The file containing the VM executable.
+   */
+  File _vmExecutable;
+  /**
+   * A mapping from Dart library URI's to the library represented by that URI.
+   */
+  LibraryMap _libraryMap;
+  /**
+   * The name of the directory within the SDK directory that contains executables.
+   */
+  static String _BIN_DIRECTORY_NAME = "bin";
+  /**
+   * The name of the directory within the SDK directory that contains Chromium.
+   */
+  static String _CHROMIUM_DIRECTORY_NAME = "chromium";
+  /**
+   * The name of the environment variable whose value is the path to the default Dart SDK directory.
+   */
+  static String _DART_SDK_ENVIRONMENT_VARIABLE_NAME = "DART_SDK";
+  /**
+   * The name of the file containing the Dartium executable on Linux.
+   */
+  static String _DARTIUM_EXECUTABLE_NAME_LINUX = "chromium/chrome";
+  /**
+   * The name of the file containing the Dartium executable on Macintosh.
+   */
+  static String _DARTIUM_EXECUTABLE_NAME_MAC = "Chromium.app/Contents/MacOS/Chromium";
+  /**
+   * The name of the file containing the Dartium executable on Windows.
+   */
+  static String _DARTIUM_EXECUTABLE_NAME_WIN = "chromium/Chrome.exe";
+  /**
+   * The name of the {@link System} property whose value is the path to the default Dart SDK
+   * directory.
+   */
+  static String _DEFAULT_DIRECTORY_PROPERTY_NAME = "com.google.dart.sdk";
+  /**
+   * The version number that is returned when the real version number could not be determined.
+   */
+  static String _DEFAULT_VERSION = "0";
+  /**
+   * The name of the directory within the SDK directory that contains documentation for the
+   * libraries.
+   */
+  static String _DOCS_DIRECTORY_NAME = "docs";
+  /**
+   * The suffix added to the name of a library to derive the name of the file containing the
+   * documentation for that library.
+   */
+  static String _DOC_FILE_SUFFIX = "_api.json";
+  /**
+   * The name of the directory within the SDK directory that contains the libraries file.
+   */
+  static String _INTERNAL_DIR = "_internal";
+  /**
+   * The name of the directory within the SDK directory that contains the libraries.
+   */
+  static String _LIB_DIRECTORY_NAME = "lib";
+  /**
+   * The name of the libraries file.
+   */
+  static String _LIBRARIES_FILE = "libraries.dart";
+  /**
+   * The name of the directory within the SDK directory that contains the packages.
+   */
+  static String _PKG_DIRECTORY_NAME = "pkg";
+  /**
+   * The name of the file within the SDK directory that contains the revision number of the SDK.
+   */
+  static String _REVISION_FILE_NAME = "revision";
+  /**
+   * The name of the file containing the VM executable on the Windows operating system.
+   */
+  static String _VM_EXECUTABLE_NAME_WIN = "dart.exe";
+  /**
+   * The name of the file containing the VM executable on non-Windows operating systems.
+   */
+  static String _VM_EXECUTABLE_NAME = "dart";
+  /**
+   * Return the default Dart SDK, or {@code null} if the directory containing the default SDK cannot
+   * be determined (or does not exist).
+   * @return the default Dart SDK
+   */
+  static DartSdk get defaultSdk {
+    File sdkDirectory = defaultSdkDirectory;
+    if (sdkDirectory == null) {
+      return null;
+    }
+    return new DartSdk(sdkDirectory);
+  }
+  /**
+   * Return the default directory for the Dart SDK, or {@code null} if the directory cannot be
+   * determined (or does not exist). The default directory is provided by a {@link System} property
+   * named {@code com.google.dart.sdk}, or, if the property is not defined, an environment variable
+   * named {@code DART_SDK}.
+   * @return the default directory for the Dart SDK
+   */
+  static File get defaultSdkDirectory {
+    String sdkProperty = System.getProperty(_DEFAULT_DIRECTORY_PROPERTY_NAME);
+    if (sdkProperty == null) {
+      sdkProperty = System.getenv(_DART_SDK_ENVIRONMENT_VARIABLE_NAME);
+      if (sdkProperty == null) {
+        return null;
+      }
+    }
+    File sdkDirectory = new File(sdkProperty);
+    if (!sdkDirectory.existsSync()) {
+      return null;
+    }
+    return sdkDirectory;
+  }
+  /**
+   * Initialize a newly created SDK to represent the Dart SDK installed in the given directory.
+   * @param sdkDirectory the directory containing the SDK
+   */
+  DartSdk(File sdkDirectory) {
+    this._sdkDirectory = getAbsoluteFile(sdkDirectory);
+    initializeSdk();
+    initializeLibraryMap();
+  }
+  /**
+   * Return the file containing the Dartium executable, or {@code null} if it does not exist.
+   * @return the file containing the Dartium executable
+   */
+  File get dartiumExecutable {
+    {
+      if (_dartiumExecutable == null) {
+        File file = newRelativeFile(_sdkDirectory, dartiumBinaryName);
+        if (file.existsSync()) {
+          _dartiumExecutable = file;
+        }
+      }
+    }
+    return _dartiumExecutable;
+  }
+  /**
+   * Return the directory where dartium can be found in the Dart SDK (the directory that will be the
+   * working directory is Dartium is invoked without changing the default).
+   * @return the directory where dartium can be found
+   */
+  File get dartiumWorkingDirectory {
+    if (OSUtilities.isWindows() || OSUtilities.isMac()) {
+      return _sdkDirectory;
+    } else {
+      return newRelativeFile(_sdkDirectory, _CHROMIUM_DIRECTORY_NAME);
+    }
+  }
+  /**
+   * Return the directory containing the SDK.
+   * @return the directory containing the SDK
+   */
+  File get directory => _sdkDirectory;
+  /**
+   * Return the directory containing documentation for the SDK.
+   * @return the SDK's documentation directory
+   */
+  File get docDirectory => newRelativeFile(_sdkDirectory, _DOCS_DIRECTORY_NAME);
+  /**
+   * Return the auxiliary documentation file for the given library, or {@code null} if no such file
+   * exists.
+   * @param libraryName the name of the library associated with the documentation file to be
+   * returned
+   * @return the auxiliary documentation file for the library
+   */
+  File getDocFileFor(String libraryName) {
+    File dir = docDirectory;
+    if (!dir.existsSync()) {
+      return null;
+    }
+    File libDir = newRelativeFile(dir, libraryName);
+    File docFile = newRelativeFile(libDir, "${libraryName}${_DOC_FILE_SUFFIX}");
+    if (docFile.existsSync()) {
+      return docFile;
+    }
+    return null;
+  }
+  /**
+   * Return the directory within the SDK directory that contains the libraries.
+   * @return the directory that contains the libraries
+   */
+  File get libraryDirectory => newRelativeFile(_sdkDirectory, _LIB_DIRECTORY_NAME);
+  /**
+   * Return the directory within the SDK directory that contains the packages.
+   * @return the directory that contains the packages
+   */
+  File get packageDirectory => newRelativeFile(directory, _PKG_DIRECTORY_NAME);
+  /**
+   * Return an array containing all of the libraries defined in this SDK.
+   * @return the libraries defined in this SDK
+   */
+  List<SdkLibrary> get sdkLibraries => _libraryMap.sdkLibraries;
+  /**
+   * Return the revision number of this SDK, or {@code "0"} if the revision number cannot be
+   * discovered.
+   * @return the revision number of this SDK
+   */
+  String get sdkVersion {
+    {
+      if (_sdkVersion == null) {
+        _sdkVersion = _DEFAULT_VERSION;
+        File revisionFile = newRelativeFile(_sdkDirectory, _REVISION_FILE_NAME);
+        try {
+          String revision = revisionFile.readAsStringSync();
+          if (revision != null) {
+            _sdkVersion = revision;
+          }
+        } on IOException catch (exception) {
+        }
+      }
+    }
+    return _sdkVersion;
+  }
+  /**
+   * Return an array containing the library URI's for the libraries defined in this SDK.
+   * @return the library URI's for the libraries defined in this SDK
+   */
+  List<String> get uris => _libraryMap.uris;
+  /**
+   * Return the file containing the VM executable, or {@code null} if it does not exist.
+   * @return the file containing the VM executable
+   */
+  File get vmExecutable {
+    {
+      if (_vmExecutable == null) {
+        File file = newRelativeFile(newRelativeFile(_sdkDirectory, _BIN_DIRECTORY_NAME), binaryName);
+        if (file.existsSync()) {
+          _vmExecutable = file;
+        }
+      }
+    }
+    return _vmExecutable;
+  }
+  /**
+   * Return {@code true} if this SDK includes documentation.
+   * @return {@code true} if this installation of the SDK has documentation
+   */
+  bool hasDocumentation() => docDirectory.existsSync();
+  /**
+   * Return {@code true} if the Dartium binary is available.
+   * @return {@code true} if the Dartium binary is available
+   */
+  bool isDartiumInstalled() => dartiumExecutable != null;
+  /**
+   * Return the file representing the library with the given {@code dart:} URI, or {@code null} if
+   * the given URI does not denote a library in this SDK.
+   * @param dartUri the URI of the library to be returned
+   * @return the file representing the specified library
+   */
+  File mapDartUri(String dartUri) {
+    SdkLibrary library = _libraryMap.getLibrary(dartUri);
+    if (library == null) {
+      return null;
+    }
+    return newRelativeFile(libraryDirectory, library.path);
+  }
+  /**
+   * Ensure that the dart VM is executable. If it is not, make it executable and log that it was
+   * necessary for us to do so.
+   */
+  void ensureVmIsExecutable() {
+  }
+  /**
+   * Return the name of the file containing the VM executable.
+   * @return the name of the file containing the VM executable
+   */
+  String get binaryName {
+    if (OSUtilities.isWindows()) {
+      return _VM_EXECUTABLE_NAME_WIN;
+    } else {
+      return _VM_EXECUTABLE_NAME;
+    }
+  }
+  /**
+   * Return the name of the file containing the Dartium executable.
+   * @return the name of the file containing the Dartium executable
+   */
+  String get dartiumBinaryName {
+    if (OSUtilities.isWindows()) {
+      return _DARTIUM_EXECUTABLE_NAME_WIN;
+    } else if (OSUtilities.isMac()) {
+      return _DARTIUM_EXECUTABLE_NAME_MAC;
+    } else {
+      return _DARTIUM_EXECUTABLE_NAME_LINUX;
+    }
+  }
+  /**
+   * Read all of the configuration files to initialize the library maps.
+   */
+  void initializeLibraryMap() {
+    try {
+      File librariesFile = newRelativeFile(newRelativeFile(libraryDirectory, _INTERNAL_DIR), _LIBRARIES_FILE);
+      String contents = librariesFile.readAsStringSync();
+      _libraryMap = new SdkLibrariesReader().readFrom(librariesFile, contents);
+    } on JavaException catch (exception) {
+      AnalysisEngine.instance.logger.logError3(exception);
+      _libraryMap = new LibraryMap();
+    }
+  }
+  /**
+   * Initialize the state of the SDK.
+   */
+  void initializeSdk() {
+    if (!OSUtilities.isWindows()) {
+      ensureVmIsExecutable();
+    }
+  }
+}
+/**
+ * Instances of the class {@code SdkLibrariesReader} read and parse the libraries file
+ * (dart-sdk/lib/_internal/libraries.dart) for information about the libraries in an SDK. The
+ * library information is represented as a Dart file containing a single top-level variable whose
+ * value is a const map. The keys of the map are the names of libraries defined in the SDK and the
+ * values in the map are info objects defining the library. For example, a subset of a typical SDK
+ * might have a libraries file that looks like the following:
+ * <pre>
+ * final Map&lt;String, LibraryInfo&gt; LIBRARIES = const &lt;LibraryInfo&gt; {
+ * // Used by VM applications
+ * "builtin" : const LibraryInfo(
+ * "builtin/builtin_runtime.dart",
+ * category: "Server",
+ * platforms: VM_PLATFORM),
+ * "compiler" : const LibraryInfo(
+ * "compiler/compiler.dart",
+ * category: "Tools",
+ * platforms: 0),
+ * };
+ * </pre>
+ */
+class SdkLibrariesReader {
+  /**
+   * Return the library map read from the given source.
+   * @return the library map read from the given source
+   */
+  LibraryMap readFrom(File librariesFile, String libraryFileContents) {
+    List<bool> foundError = [false];
+    AnalysisErrorListener errorListener = new AnalysisErrorListener_3(foundError);
+    Source source = new FileBasedSource.con2(null, librariesFile, false);
+    StringScanner scanner = new StringScanner(source, libraryFileContents, errorListener);
+    Parser parser = new Parser(source, errorListener);
+    CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize());
+    SdkLibrariesReader_LibraryBuilder libraryBuilder = new SdkLibrariesReader_LibraryBuilder();
+    if (!foundError[0]) {
+      unit.accept(libraryBuilder);
+    }
+    return libraryBuilder.librariesMap;
+  }
+}
+class SdkLibrariesReader_LibraryBuilder extends RecursiveASTVisitor<Object> {
+  /**
+   * The prefix added to the name of a library to form the URI used in code to reference the
+   * library.
+   */
+  static String _LIBRARY_PREFIX = "dart:";
+  /**
+   * The name of the optional parameter used to indicate whether the library is an implementation
+   * library.
+   */
+  static String _IMPLEMENTATION = "implementation";
+  /**
+   * The name of the optional parameter used to indicate whether the library is documented.
+   */
+  static String _DOCUMENTED = "documented";
+  /**
+   * The name of the optional parameter used to specify the category of the library.
+   */
+  static String _CATEGORY = "category";
+  /**
+   * The name of the optional parameter used to specify the platforms on which the library can be
+   * used.
+   */
+  static String _PLATFORMS = "platforms";
+  /**
+   * The value of the {@link #PLATFORMS platforms} parameter used to specify that the library can
+   * be used on the VM.
+   */
+  static String _VM_PLATFORM = "VM_PLATFORM";
+  /**
+   * The library map that is populated by visiting the AST structure parsed from the contents of
+   * the libraries file.
+   */
+  LibraryMap _librariesMap = new LibraryMap();
+  /**
+   * Return the library map that was populated by visiting the AST structure parsed from the
+   * contents of the libraries file.
+   * @return the library map describing the contents of the SDK
+   */
+  LibraryMap get librariesMap => _librariesMap;
+  Object visitMapLiteralEntry(MapLiteralEntry node) {
+    String libraryName = null;
+    Expression key3 = node.key;
+    if (key3 is SimpleStringLiteral) {
+      libraryName = "${_LIBRARY_PREFIX}${((key3 as SimpleStringLiteral)).value}";
+    }
+    Expression value8 = node.value;
+    if (value8 is InstanceCreationExpression) {
+      SdkLibraryImpl library = new SdkLibraryImpl(libraryName);
+      List<Expression> arguments6 = ((value8 as InstanceCreationExpression)).argumentList.arguments;
+      for (Expression argument in arguments6) {
+        if (argument is SimpleStringLiteral) {
+          library.path = ((argument as SimpleStringLiteral)).value;
+        } else if (argument is NamedExpression) {
+          String name18 = ((argument as NamedExpression)).name.label.name;
+          Expression expression15 = ((argument as NamedExpression)).expression;
+          if (name18 == _CATEGORY) {
+            library.category = ((expression15 as SimpleStringLiteral)).value;
+          } else if (name18 == _IMPLEMENTATION) {
+            library.implementation = ((expression15 as BooleanLiteral)).value;
+          } else if (name18 == _DOCUMENTED) {
+            library.documented = ((expression15 as BooleanLiteral)).value;
+          } else if (name18 == _PLATFORMS) {
+            if (expression15 is SimpleIdentifier) {
+              String identifier = ((expression15 as SimpleIdentifier)).name;
+              if (identifier == _VM_PLATFORM) {
+                library.setVmLibrary();
+              } else {
+                library.setDart2JsLibrary();
+              }
+            }
+          }
+        }
+      }
+      _librariesMap.setLibrary(libraryName, library);
+    }
+    return null;
+  }
+}
+class AnalysisErrorListener_3 implements AnalysisErrorListener {
+  List<bool> foundError;
+  AnalysisErrorListener_3(this.foundError);
+  void onError(AnalysisError error) {
+    foundError[0] = true;
+  }
+}
+/**
+ * Instances of the class {@code SdkLibrary} represent the information known about a single library
+ * within the SDK.
+ */
+class SdkLibraryImpl implements SdkLibrary {
+  /**
+   * The short name of the library. This is the name used after {@code dart:} in a URI.
+   */
+  String _shortName = null;
+  /**
+   * The path to the file defining the library. The path is relative to the {@code lib} directory
+   * within the SDK.
+   */
+  String _path = null;
+  /**
+   * The name of the category containing the library. Unless otherwise specified in the libraries
+   * file all libraries are assumed to be shared between server and client.
+   */
+  String _category = "Shared";
+  /**
+   * A flag indicating whether the library is documented.
+   */
+  bool _documented = true;
+  /**
+   * A flag indicating whether the library is an implementation library.
+   */
+  bool _implementation = false;
+  /**
+   * An encoding of which platforms this library is intended to work on.
+   */
+  int _platforms = 0;
+  /**
+   * The bit mask used to access the bit representing the flag indicating whether a library is
+   * intended to work on the dart2js platform.
+   */
+  static int DART2JS_PLATFORM = 1;
+  /**
+   * The bit mask used to access the bit representing the flag indicating whether a library is
+   * intended to work on the VM platform.
+   */
+  static int VM_PLATFORM = 2;
+  /**
+   * Initialize a newly created library to represent the library with the given name.
+   * @param name the short name of the library
+   */
+  SdkLibraryImpl(String name) {
+    this._shortName = name;
+  }
+  String get category => _category;
+  String get path => _path;
+  String get shortName => _shortName;
+  bool isDart2JsLibrary() => (_platforms & DART2JS_PLATFORM) != 0;
+  bool isDocumented() => _documented;
+  bool isImplementation() => _implementation;
+  /**
+   * Return {@code true} if library can be used for both client and server
+   */
+  bool isShared() => _category == "Shared";
+  /**
+   * Return {@code true} if this library can be run on the VM.
+   * @return {@code true} if this library can be run on the VM
+   */
+  bool isVmLibrary() => (_platforms & VM_PLATFORM) != 0;
+  /**
+   * Set the name of the category containing the library to the given name.
+   * @param category the name of the category containing the library
+   */
+  void set category(String category2) {
+    this._category = category2;
+  }
+  /**
+   * Record that this library can be compiled to JavaScript by dart2js.
+   */
+  void setDart2JsLibrary() {
+    _platforms |= DART2JS_PLATFORM;
+  }
+  /**
+   * Set whether the library is documented to match the given value.
+   * @param documented {@code true} if the library is documented
+   */
+  void set documented(bool documented2) {
+    this._documented = documented2;
+  }
+  /**
+   * Set whether the library is an implementation library to match the given value.
+   * @param implementation {@code true} if the library is an implementation library
+   */
+  void set implementation(bool implementation2) {
+    this._implementation = implementation2;
+  }
+  /**
+   * Set the path to the file defining the library to the given path. The path is relative to the{@code lib} directory within the SDK.
+   * @param path the path to the file defining the library
+   */
+  void set path(String path2) {
+    this._path = path2;
+  }
+  /**
+   * Record that this library can be run on the VM.
+   */
+  void setVmLibrary() {
+    _platforms |= VM_PLATFORM;
+  }
+}
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/lib/src/generated/source.dart b/pkg/analyzer-experimental/lib/src/generated/source.dart
index 4efbb17..811dce2 100644
--- a/pkg/analyzer-experimental/lib/src/generated/source.dart
+++ b/pkg/analyzer-experimental/lib/src/generated/source.dart
@@ -3,9 +3,405 @@
 
 library engine.source;
 
+import 'dart:io';
+import 'dart:uri';
 import 'java_core.dart';
+import 'package:analyzer-experimental/src/generated/sdk.dart' show DartSdk;
 
 /**
+ * Instances of the class {@code FileUriResolver} resolve {@code file} URI's.
+ */
+class FileUriResolver extends UriResolver {
+  /**
+   * The name of the {@code file} scheme.
+   */
+  static String _FILE_SCHEME = "file";
+  /**
+   * Return {@code true} if the given URI is a {@code file} URI.
+   * @param uri the URI being tested
+   * @return {@code true} if the given URI is a {@code file} URI
+   */
+  static bool isFileUri(Uri uri) => uri.scheme == _FILE_SCHEME;
+  /**
+   * Initialize a newly created resolver to resolve {@code file} URI's relative to the given root
+   * directory.
+   */
+  FileUriResolver() : super() {
+  }
+  Source resolveAbsolute(SourceFactory factory, Uri uri) {
+    if (!isFileUri(uri)) {
+      return null;
+    }
+    return new FileBasedSource.con1(factory, newFileFromUri(uri));
+  }
+}
+/**
+ * Instances of the class {@code DartUriResolver} resolve {@code dart} URI's.
+ */
+class DartUriResolver extends UriResolver {
+  /**
+   * The Dart SDK against which URI's are to be resolved.
+   */
+  DartSdk _sdk;
+  /**
+   * The name of the {@code dart} scheme.
+   */
+  static String _DART_SCHEME = "dart";
+  /**
+   * Return {@code true} if the given URI is a {@code dart:} URI.
+   * @param uri the URI being tested
+   * @return {@code true} if the given URI is a {@code dart:} URI
+   */
+  static bool isDartUri(Uri uri) => uri.scheme == _DART_SCHEME;
+  /**
+   * Initialize a newly created resolver to resolve Dart URI's against the given platform within the
+   * given Dart SDK.
+   * @param sdk the Dart SDK against which URI's are to be resolved
+   */
+  DartUriResolver(DartSdk sdk) {
+    this._sdk = sdk;
+  }
+  Source resolveAbsolute(SourceFactory factory, Uri uri) {
+    if (!isDartUri(uri)) {
+      return null;
+    }
+    File resolvedFile = _sdk.mapDartUri(uri.toString());
+    return new FileBasedSource.con2(factory, resolvedFile, true);
+  }
+}
+/**
+ * Instances of the class {@code FileBasedSource} implement a source that represents a file.
+ */
+class FileBasedSource implements Source {
+  /**
+   * The source factory that created this source and that should be used to resolve URI's against
+   * this source.
+   */
+  SourceFactory _factory;
+  /**
+   * The file represented by this source.
+   */
+  File _file;
+  /**
+   * A flag indicating whether this source is in one of the system libraries.
+   */
+  bool _inSystemLibrary = false;
+  /**
+   * Initialize a newly created source object. The source object is assumed to not be in a system
+   * library.
+   * @param factory the source factory that created this source
+   * @param file the file represented by this source
+   */
+  FileBasedSource.con1(SourceFactory factory, File file) {
+    _jtd_constructor_243_impl(factory, file);
+  }
+  _jtd_constructor_243_impl(SourceFactory factory, File file) {
+    _jtd_constructor_244_impl(factory, file, false);
+  }
+  /**
+   * Initialize a newly created source object.
+   * @param factory the source factory that created this source
+   * @param file the file represented by this source
+   * @param inSystemLibrary {@code true} if this source is in one of the system libraries
+   */
+  FileBasedSource.con2(SourceFactory factory2, File file3, bool inSystemLibrary2) {
+    _jtd_constructor_244_impl(factory2, file3, inSystemLibrary2);
+  }
+  _jtd_constructor_244_impl(SourceFactory factory2, File file3, bool inSystemLibrary2) {
+    this._factory = factory2;
+    this._file = file3;
+    this._inSystemLibrary = inSystemLibrary2;
+  }
+  bool operator ==(Object object) => object != null && identical(this.runtimeType, object.runtimeType) && _file == ((object as FileBasedSource))._file;
+  void getContents(Source_ContentReceiver receiver) {
+    receiver.accept2(_file.readAsStringSync());
+  }
+  String get fullName => _file.fullPathSync();
+  String get shortName => _file.name;
+  int get hashCode => _file.hashCode;
+  bool isInSystemLibrary() => _inSystemLibrary;
+  Source resolve(String uri) => _factory.resolveUri(this, uri);
+  String toString() {
+    if (_file == null) {
+      return "<unknown source>";
+    }
+    return _file.fullPathSync();
+  }
+  /**
+   * Return the file represented by this source. This is an internal method that is only intended to
+   * be used by {@link UriResolver}.
+   * @return the file represented by this source
+   */
+  File get file => _file;
+}
+/**
+ * Instances of the class {@link DirectoryBasedSourceContainer} represent a source container that
+ * contains all sources within a given directory.
+ */
+class DirectoryBasedSourceContainer implements SourceContainer {
+  /**
+   * Append the system file separator to the given path unless the path already ends with a
+   * separator.
+   * @param path the path to which the file separator is to be added
+   * @return a path that ends with the system file separator
+   */
+  static String appendFileSeparator(String path) {
+    if (path == null || path.length <= 0 || path.codeUnitAt(path.length - 1) == System.pathSeparatorChar) {
+      return path;
+    }
+    return "${path}${System.pathSeparator}";
+  }
+  /**
+   * The container's path (not {@code null}).
+   */
+  String _path;
+  /**
+   * Construct a container representing the specified directory and containing any sources whose{@link Source#getFullName()} starts with the directory's path. This is a convenience method,
+   * fully equivalent to {@link DirectoryBasedSourceContainer#DirectoryBasedSourceContainer(String)}.
+   * @param directory the directory (not {@code null})
+   */
+  DirectoryBasedSourceContainer.con1(File directory) {
+    _jtd_constructor_241_impl(directory);
+  }
+  _jtd_constructor_241_impl(File directory) {
+    _jtd_constructor_242_impl(directory.fullPathSync());
+  }
+  /**
+   * Construct a container representing the specified path and containing any sources whose{@link Source#getFullName()} starts with the specified path.
+   * @param path the path (not {@code null} and not empty)
+   */
+  DirectoryBasedSourceContainer.con2(String path3) {
+    _jtd_constructor_242_impl(path3);
+  }
+  _jtd_constructor_242_impl(String path3) {
+    this._path = appendFileSeparator(path3);
+  }
+  bool contains(Source source) => source.fullName.startsWith(_path);
+  bool operator ==(Object obj) => (obj is DirectoryBasedSourceContainer) && ((obj as DirectoryBasedSourceContainer)).path == path;
+  /**
+   * Answer the receiver's path, used to determine if a source is contained in the receiver.
+   * @return the path (not {@code null}, not empty)
+   */
+  String get path => _path;
+  int get hashCode => _path.hashCode;
+}
+/**
+ * Instances of the class {@code PackageUriResolver} resolve {@code package} URI's in the context of
+ * an application.
+ */
+class PackageUriResolver extends UriResolver {
+  /**
+   * The package directories that {@code package} URI's are assumed to be relative to.
+   */
+  List<File> _packagesDirectories;
+  /**
+   * The name of the {@code package} scheme.
+   */
+  static String _PACKAGE_SCHEME = "package";
+  /**
+   * Return {@code true} if the given URI is a {@code package} URI.
+   * @param uri the URI being tested
+   * @return {@code true} if the given URI is a {@code package} URI
+   */
+  static bool isPackageUri(Uri uri) => uri.scheme == _PACKAGE_SCHEME;
+  /**
+   * Initialize a newly created resolver to resolve {@code package} URI's relative to the given
+   * package directories.
+   * @param packagesDirectories the package directories that {@code package} URI's are assumed to be
+   * relative to
+   */
+  PackageUriResolver(List<File> packagesDirectories) {
+    if (packagesDirectories.length < 1) {
+      throw new IllegalArgumentException("At least one package directory must be provided");
+    }
+    this._packagesDirectories = packagesDirectories;
+  }
+  Source resolveAbsolute(SourceFactory factory, Uri uri) {
+    if (!isPackageUri(uri)) {
+      return null;
+    }
+    String path4 = uri.path;
+    if (path4 == null) {
+      path4 = uri.path;
+      if (path4 == null) {
+        return null;
+      }
+    }
+    for (File packagesDirectory in _packagesDirectories) {
+      File resolvedFile = newRelativeFile(packagesDirectory, path4);
+      if (resolvedFile.existsSync()) {
+        return new FileBasedSource.con1(factory, resolvedFile);
+      }
+    }
+    return new FileBasedSource.con1(factory, newRelativeFile(_packagesDirectories[0], path4));
+  }
+}
+/**
+ * The abstract class {@code UriResolver} defines the behavior of objects that are used to resolve
+ * URI's for a source factory. Subclasses of this class are expected to resolve a single scheme of
+ * absolute URI.
+ */
+abstract class UriResolver {
+  /**
+   * Initialize a newly created resolver.
+   */
+  UriResolver() : super() {
+  }
+  /**
+   * Working on behalf of the given source factory, resolve the (possibly relative) contained URI
+   * against the URI associated with the containing source object. Return a {@link Source source}representing the file to which it was resolved, or {@code null} if it could not be resolved.
+   * @param factory the source factory requesting the resolution of the URI
+   * @param containingSource the source containing the given URI
+   * @param containedUri the (possibly relative) URI to be resolved against the containing source
+   * @return a {@link Source source} representing the URI to which given URI was resolved
+   */
+  Source resolve(SourceFactory factory, Source containingSource, Uri containedUri) {
+    if (containedUri.isAbsolute()) {
+      return resolveAbsolute(factory, containedUri);
+    } else {
+      return resolveRelative(factory, containingSource, containedUri);
+    }
+  }
+  /**
+   * Resolve the given absolute URI. Return a {@link Source source} representing the file to which
+   * it was resolved, or {@code null} if it could not be resolved.
+   * @param uri the URI to be resolved
+   * @return a {@link Source source} representing the URI to which given URI was resolved
+   */
+  Source resolveAbsolute(SourceFactory factory, Uri uri);
+  /**
+   * Resolve the relative (contained) URI against the URI associated with the containing source
+   * object. Return a {@link Source source} representing the file to which it was resolved, or{@code null} if it could not be resolved.
+   * @param containingSource the source containing the given URI
+   * @param containedUri the (possibly relative) URI to be resolved against the containing source
+   * @return a {@link Source source} representing the URI to which given URI was resolved
+   */
+  Source resolveRelative(SourceFactory factory, Source containingSource, Uri containedUri) {
+    if (containingSource is FileBasedSource) {
+      try {
+        Uri resolvedUri = newUriFromFile(((containingSource as FileBasedSource)).file).resolveUri(containedUri);
+        return new FileBasedSource.con1(factory, newFileFromUri(resolvedUri));
+      } on JavaException catch (exception) {
+      }
+    }
+    return null;
+  }
+}
+/**
+ * Instances of the class {@code SourceFactory} resolve possibly relative URI's against an existing{@link Source source}.
+ */
+class SourceFactory {
+  /**
+   * The resolvers used to resolve absolute URI's.
+   */
+  List<UriResolver> _resolvers;
+  /**
+   * A cache of content used to override the default content of a source.
+   */
+  ContentCache _contentCache;
+  /**
+   * Initialize a newly created source factory.
+   * @param contentCache the cache holding content used to override the default content of a source.
+   * @param resolvers the resolvers used to resolve absolute URI's
+   */
+  SourceFactory.con1(ContentCache contentCache2, List<UriResolver> resolvers2) {
+    _jtd_constructor_247_impl(contentCache2, resolvers2);
+  }
+  _jtd_constructor_247_impl(ContentCache contentCache2, List<UriResolver> resolvers2) {
+    this._contentCache = contentCache2;
+    this._resolvers = resolvers2;
+  }
+  /**
+   * Initialize a newly created source factory.
+   * @param resolvers the resolvers used to resolve absolute URI's
+   */
+  SourceFactory.con2(List<UriResolver> resolvers) {
+    _jtd_constructor_248_impl(resolvers);
+  }
+  _jtd_constructor_248_impl(List<UriResolver> resolvers) {
+    _jtd_constructor_247_impl(new ContentCache(), [resolvers]);
+  }
+  /**
+   * Return a source container representing the given directory
+   * @param directory the directory (not {@code null})
+   * @return the source container representing the directory (not {@code null})
+   */
+  SourceContainer forDirectory(File directory) => new DirectoryBasedSourceContainer.con1(directory);
+  /**
+   * Return a source object representing the given file.
+   * @param file the file to be represented by the returned source object
+   * @return a source object representing the given file
+   */
+  Source forFile(File file) => new FileBasedSource.con1(this, file);
+  /**
+   * Return a source object representing the given absolute URI, or {@code null} if the URI is not a
+   * valid URI or if it is not an absolute URI.
+   * @param absoluteUri the absolute URI to be resolved
+   * @return a source object representing the absolute URI
+   */
+  Source forUri(String absoluteUri) {
+    try {
+      Uri uri = new Uri.fromComponents(path: absoluteUri);
+      if (uri.isAbsolute()) {
+        return resolveUri2(null, uri);
+      }
+    } on URISyntaxException catch (exception) {
+    }
+    return null;
+  }
+  /**
+   * Return a source object representing the URI that results from resolving the given (possibly
+   * relative) contained URI against the URI associated with an existing source object, or{@code null} if either the contained URI is invalid or if it cannot be resolved against the
+   * source object's URI.
+   * @param containingSource the source containing the given URI
+   * @param containedUri the (possibly relative) URI to be resolved against the containing source
+   * @return the source representing the contained URI
+   */
+  Source resolveUri(Source containingSource, String containedUri) {
+    try {
+      return resolveUri2(containingSource, new Uri.fromComponents(path: containedUri));
+    } on URISyntaxException catch (exception) {
+      return null;
+    }
+  }
+  /**
+   * Set the contents of the given source to the given contents. This has the effect of overriding
+   * the default contents of the source. If the contents are {@code null} the override is removed so
+   * that the default contents will be returned.
+   * @param source the source whose contents are being overridden
+   * @param contents the new contents of the source
+   */
+  void setContents(Source source, String contents) {
+    _contentCache.setContents(source, contents);
+  }
+  /**
+   * Return the contents of the given source, or {@code null} if this factory does not override the
+   * contents of the source.
+   * <p>
+   * <b>Note:</b> This method is not intended to be used except by{@link FileBasedSource#getContents(com.google.dart.engine.source.Source.ContentReceiver)}.
+   * @param source the source whose content is to be returned
+   * @return the contents of the given source
+   */
+  String getContents(Source source) => _contentCache.getContents(source);
+  /**
+   * Return a source object representing the URI that results from resolving the given (possibly
+   * relative) contained URI against the URI associated with an existing source object, or{@code null} if either the contained URI is invalid or if it cannot be resolved against the
+   * source object's URI.
+   * @param containingSource the source containing the given URI
+   * @param containedUri the (possibly relative) URI to be resolved against the containing source
+   * @return the source representing the contained URI
+   */
+  Source resolveUri2(Source containingSource, Uri containedUri) {
+    for (UriResolver resolver in _resolvers) {
+      Source result = resolver.resolve(this, containingSource, containedUri);
+      if (result != null) {
+        return result;
+      }
+    }
+    return null;
+  }
+}
+/**
  * The interface {@code Source} defines the behavior of objects representing source code that can be
  * compiled.
  */
@@ -76,6 +472,55 @@
   void accept2(String contents);
 }
 /**
+ * Instances of class {@code ContentCache} hold content used to override the default content of a{@link Source}.
+ */
+class ContentCache {
+  /**
+   * A table mapping sources to the contents of those sources. This is used to override the default
+   * contents of a source.
+   */
+  Map<Source, String> _contentMap = new Map<Source, String>();
+  /**
+   * Return the contents of the given source, or {@code null} if this cache does not override the
+   * contents of the source.
+   * <p>
+   * <b>Note:</b> This method is not intended to be used except by{@link SourceFactory#getContents(com.google.dart.engine.source.Source.ContentReceiver)}.
+   * @param source the source whose content is to be returned
+   * @return the contents of the given source
+   */
+  String getContents(Source source) => _contentMap[source];
+  /**
+   * Set the contents of the given source to the given contents. This has the effect of overriding
+   * the default contents of the source. If the contents are {@code null} the override is removed so
+   * that the default contents will be returned.
+   * @param source the source whose contents are being overridden
+   * @param contents the new contents of the source
+   */
+  void setContents(Source source, String contents) {
+    if (contents == null) {
+      _contentMap.remove(source);
+    } else {
+      _contentMap[source] = contents;
+    }
+  }
+}
+/**
+ * The interface {@code SourceContainer} is used by clients to define a collection of sources
+ * <p>
+ * Source containers are not used within analysis engine, but can be used by clients to group
+ * sources for the purposes of accessing composite dependency information. For example, the Eclipse
+ * client uses source containers to represent Eclipse projects, which allows it to easily compute
+ * project-level dependencies.
+ */
+abstract class SourceContainer {
+  /**
+   * Determine if the specified source is part of the receiver's collection of sources.
+   * @param source the source in question
+   * @return {@code true} if the receiver contains the source, else {@code false}
+   */
+  bool contains(Source source);
+}
+/**
  * Instances of the class {@code LineInfo} encapsulate information about line and column information
  * within a source file.
  */
@@ -145,4 +590,35 @@
    * @return the one-based index of the line containing the character
    */
   int get lineNumber => _lineNumber;
+}
+/**
+ * The enumeration {@code SourceKind} defines the different kinds of sources that are known to the
+ * analysis engine.
+ */
+class SourceKind {
+  /**
+   * A source containing HTML. The HTML might or might not contain Dart scripts.
+   */
+  static final SourceKind HTML = new SourceKind('HTML', 0);
+  /**
+   * A Dart compilation unit that is not a part of another library. Libraries might or might not
+   * contain any directives, including a library directive.
+   */
+  static final SourceKind LIBRARY = new SourceKind('LIBRARY', 1);
+  /**
+   * A Dart compilation unit that is part of another library. Parts contain a part-of directive.
+   */
+  static final SourceKind PART = new SourceKind('PART', 2);
+  /**
+   * An unknown kind of source. Used both when it is not possible to identify the kind of a source
+   * and also when the kind of a source is not known without performing a computation and the client
+   * does not want to spend the time to identify the kind.
+   */
+  static final SourceKind UNKNOWN = new SourceKind('UNKNOWN', 3);
+  static final List<SourceKind> values = [HTML, LIBRARY, PART, UNKNOWN];
+  final String __name;
+  final int __ordinal;
+  SourceKind(this.__name, this.__ordinal) {
+  }
+  String toString() => __name;
 }
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/test/generated/ast_test.dart b/pkg/analyzer-experimental/test/generated/ast_test.dart
new file mode 100644
index 0000000..3246180
--- /dev/null
+++ b/pkg/analyzer-experimental/test/generated/ast_test.dart
@@ -0,0 +1,2710 @@
+// This code was auto-generated, is not intended to be edited, and is subject to
+// significant change. Please see the README file for more information.
+
+library engine.ast_test;
+
+import 'dart:collection';
+import 'package:analyzer-experimental/src/generated/java_core.dart';
+import 'package:analyzer-experimental/src/generated/java_engine.dart';
+import 'package:analyzer-experimental/src/generated/java_junit.dart';
+import 'package:analyzer-experimental/src/generated/source.dart';
+import 'package:analyzer-experimental/src/generated/error.dart';
+import 'package:analyzer-experimental/src/generated/scanner.dart';
+import 'package:analyzer-experimental/src/generated/ast.dart';
+import 'package:analyzer-experimental/src/generated/utilities_dart.dart';
+import 'package:analyzer-experimental/src/generated/element.dart' show ClassElement;
+import 'package:unittest/unittest.dart' as _ut;
+import 'parser_test.dart' show ParserTestCase;
+import 'test_support.dart';
+import 'scanner_test.dart' show TokenFactory;
+
+class NodeLocatorTest extends ParserTestCase {
+  void test_offset() {
+    CompilationUnit unit = ParserTestCase.parseCompilationUnit("library myLib;", []);
+    assertLocate(unit, 10, SimpleIdentifier);
+  }
+  void test_range() {
+    CompilationUnit unit = ParserTestCase.parseCompilationUnit("library myLib;", []);
+    assertLocate2(unit, 4, 10, LibraryDirective);
+  }
+  void assertLocate(CompilationUnit unit, int offset, Type expectedClass) {
+    assertLocate2(unit, offset, offset, expectedClass);
+  }
+  void assertLocate2(CompilationUnit unit, int start, int end, Type expectedClass) {
+    NodeLocator locator = new NodeLocator.con2(start, end);
+    ASTNode node = locator.searchWithin(unit);
+    JUnitTestCase.assertNotNull(node);
+    JUnitTestCase.assertTrueMsg("Node starts after range", node.offset <= start);
+    JUnitTestCase.assertTrueMsg("Node ends before range", node.offset + node.length > end);
+    EngineTestCase.assertInstanceOf(expectedClass, node);
+  }
+  static dartSuite() {
+    _ut.group('NodeLocatorTest', () {
+      _ut.test('test_offset', () {
+        final __test = new NodeLocatorTest();
+        runJUnitTest(__test, __test.test_offset);
+      });
+      _ut.test('test_range', () {
+        final __test = new NodeLocatorTest();
+        runJUnitTest(__test, __test.test_range);
+      });
+    });
+  }
+}
+/**
+ * The class {@code ASTFactory} defines utility methods that can be used to create AST nodes. The
+ * nodes that are created are complete in the sense that all of the tokens that would have been
+ * associated with the nodes by a parser are also created, but the token stream is not constructed.
+ */
+class ASTFactory {
+  static AdjacentStrings adjacentStrings(List<StringLiteral> strings) => new AdjacentStrings.full(list(strings));
+  static Annotation annotation(Identifier name) => new Annotation.full(TokenFactory.token3(TokenType.AT), name, null, null, null);
+  static Annotation annotation2(Identifier name, SimpleIdentifier constructorName, ArgumentList arguments) => new Annotation.full(TokenFactory.token3(TokenType.AT), name, TokenFactory.token3(TokenType.PERIOD), constructorName, arguments);
+  static ArgumentDefinitionTest argumentDefinitionTest(String identifier) => new ArgumentDefinitionTest.full(TokenFactory.token3(TokenType.QUESTION), identifier2(identifier));
+  static ArgumentList argumentList(List<Expression> arguments) => new ArgumentList.full(TokenFactory.token3(TokenType.OPEN_PAREN), list(arguments), TokenFactory.token3(TokenType.CLOSE_PAREN));
+  static AsExpression asExpression(Expression expression, TypeName type) => new AsExpression.full(expression, TokenFactory.token(Keyword.AS), type);
+  static AssertStatement assertStatement(Expression condition) => new AssertStatement.full(TokenFactory.token(Keyword.ASSERT), TokenFactory.token3(TokenType.OPEN_PAREN), condition, TokenFactory.token3(TokenType.CLOSE_PAREN), TokenFactory.token3(TokenType.SEMICOLON));
+  static AssignmentExpression assignmentExpression(Expression leftHandSide, TokenType operator, Expression rightHandSide) => new AssignmentExpression.full(leftHandSide, TokenFactory.token3(operator), rightHandSide);
+  static BinaryExpression binaryExpression(Expression leftOperand, TokenType operator, Expression rightOperand) => new BinaryExpression.full(leftOperand, TokenFactory.token3(operator), rightOperand);
+  static Block block(List<Statement> statements) => new Block.full(TokenFactory.token3(TokenType.OPEN_CURLY_BRACKET), list(statements), TokenFactory.token3(TokenType.CLOSE_CURLY_BRACKET));
+  static BlockFunctionBody blockFunctionBody(List<Statement> statements) => new BlockFunctionBody.full(block(statements));
+  static BooleanLiteral booleanLiteral(bool value) => new BooleanLiteral.full(value ? TokenFactory.token(Keyword.TRUE) : TokenFactory.token(Keyword.FALSE), value);
+  static BreakStatement breakStatement() => new BreakStatement.full(TokenFactory.token(Keyword.BREAK), null, TokenFactory.token3(TokenType.SEMICOLON));
+  static BreakStatement breakStatement2(String label) => new BreakStatement.full(TokenFactory.token(Keyword.BREAK), identifier2(label), TokenFactory.token3(TokenType.SEMICOLON));
+  static IndexExpression cascadedIndexExpression(Expression index) => new IndexExpression.forCascade_full(TokenFactory.token3(TokenType.PERIOD_PERIOD), TokenFactory.token3(TokenType.OPEN_SQUARE_BRACKET), index, TokenFactory.token3(TokenType.CLOSE_SQUARE_BRACKET));
+  static MethodInvocation cascadedMethodInvocation(String methodName, List<Expression> arguments) => new MethodInvocation.full(null, TokenFactory.token3(TokenType.PERIOD_PERIOD), identifier2(methodName), argumentList(arguments));
+  static PropertyAccess cascadedPropertyAccess(String propertyName) => new PropertyAccess.full(null, TokenFactory.token3(TokenType.PERIOD_PERIOD), identifier2(propertyName));
+  static CascadeExpression cascadeExpression(Expression target, List<Expression> cascadeSections) => new CascadeExpression.full(target, list(cascadeSections));
+  static CatchClause catchClause(String exceptionParameter, List<Statement> statements) => catchClause5(null, exceptionParameter, null, statements);
+  static CatchClause catchClause2(String exceptionParameter, String stackTraceParameter, List<Statement> statements) => catchClause5(null, exceptionParameter, stackTraceParameter, statements);
+  static CatchClause catchClause3(TypeName exceptionType, List<Statement> statements) => catchClause5(exceptionType, null, null, statements);
+  static CatchClause catchClause4(TypeName exceptionType, String exceptionParameter, List<Statement> statements) => catchClause5(exceptionType, exceptionParameter, null, statements);
+  static CatchClause catchClause5(TypeName exceptionType, String exceptionParameter, String stackTraceParameter, List<Statement> statements) => new CatchClause.full(exceptionType == null ? null : TokenFactory.token4(TokenType.IDENTIFIER, "on"), exceptionType, exceptionParameter == null ? null : TokenFactory.token(Keyword.CATCH), exceptionParameter == null ? null : TokenFactory.token3(TokenType.OPEN_PAREN), identifier2(exceptionParameter), stackTraceParameter == null ? null : TokenFactory.token3(TokenType.COMMA), stackTraceParameter == null ? null : identifier2(stackTraceParameter), exceptionParameter == null ? null : TokenFactory.token3(TokenType.CLOSE_PAREN), block(statements));
+  static ClassDeclaration classDeclaration(Keyword abstractKeyword, String name, TypeParameterList typeParameters, ExtendsClause extendsClause, WithClause withClause, ImplementsClause implementsClause, List<ClassMember> members) => new ClassDeclaration.full(null, null, abstractKeyword == null ? null : TokenFactory.token(abstractKeyword), TokenFactory.token(Keyword.CLASS), identifier2(name), typeParameters, extendsClause, withClause, implementsClause, TokenFactory.token3(TokenType.OPEN_CURLY_BRACKET), list(members), TokenFactory.token3(TokenType.CLOSE_CURLY_BRACKET));
+  static ClassTypeAlias classTypeAlias(String name, TypeParameterList typeParameters, Keyword abstractKeyword, TypeName superclass, WithClause withClause, ImplementsClause implementsClause) => new ClassTypeAlias.full(null, null, TokenFactory.token(Keyword.TYPEDEF), identifier2(name), typeParameters, TokenFactory.token3(TokenType.EQ), abstractKeyword == null ? null : TokenFactory.token(abstractKeyword), superclass, withClause, implementsClause, TokenFactory.token3(TokenType.SEMICOLON));
+  static CompilationUnit compilationUnit() => compilationUnit8(null, null, null);
+  static CompilationUnit compilationUnit2(List<CompilationUnitMember> declarations) => compilationUnit8(null, null, list(declarations));
+  static CompilationUnit compilationUnit3(List<Directive> directives) => compilationUnit8(null, list(directives), null);
+  static CompilationUnit compilationUnit4(List<Directive> directives, List<CompilationUnitMember> declarations) => compilationUnit8(null, directives, declarations);
+  static CompilationUnit compilationUnit5(String scriptTag) => compilationUnit8(scriptTag, null, null);
+  static CompilationUnit compilationUnit6(String scriptTag, List<CompilationUnitMember> declarations) => compilationUnit8(scriptTag, null, list(declarations));
+  static CompilationUnit compilationUnit7(String scriptTag, List<Directive> directives) => compilationUnit8(scriptTag, list(directives), null);
+  static CompilationUnit compilationUnit8(String scriptTag4, List<Directive> directives, List<CompilationUnitMember> declarations) => new CompilationUnit.full(TokenFactory.token3(TokenType.EOF), scriptTag4 == null ? null : scriptTag(scriptTag4), directives == null ? new List<Directive>() : directives, declarations == null ? new List<CompilationUnitMember>() : declarations, TokenFactory.token3(TokenType.EOF));
+  static ConditionalExpression conditionalExpression(Expression condition, Expression thenExpression, Expression elseExpression) => new ConditionalExpression.full(condition, TokenFactory.token3(TokenType.QUESTION), thenExpression, TokenFactory.token3(TokenType.COLON), elseExpression);
+  static ConstructorDeclaration constructorDeclaration(Identifier returnType, String name, FormalParameterList parameters, List<ConstructorInitializer> initializers) => new ConstructorDeclaration.full(null, null, TokenFactory.token(Keyword.EXTERNAL), null, null, returnType, name == null ? null : TokenFactory.token3(TokenType.PERIOD), name == null ? null : identifier2(name), parameters, initializers == null || initializers.isEmpty ? null : TokenFactory.token3(TokenType.PERIOD), initializers == null ? new List<ConstructorInitializer>() : initializers, null, emptyFunctionBody());
+  static ConstructorDeclaration constructorDeclaration2(Keyword constKeyword, Keyword factoryKeyword, Identifier returnType, String name, FormalParameterList parameters, List<ConstructorInitializer> initializers, FunctionBody body) => new ConstructorDeclaration.full(null, null, null, constKeyword == null ? null : TokenFactory.token(constKeyword), factoryKeyword == null ? null : TokenFactory.token(factoryKeyword), returnType, name == null ? null : TokenFactory.token3(TokenType.PERIOD), name == null ? null : identifier2(name), parameters, initializers == null || initializers.isEmpty ? null : TokenFactory.token3(TokenType.PERIOD), initializers == null ? new List<ConstructorInitializer>() : initializers, null, body);
+  static ConstructorFieldInitializer constructorFieldInitializer(bool prefixedWithThis, String fieldName, Expression expression) => new ConstructorFieldInitializer.full(prefixedWithThis ? TokenFactory.token(Keyword.THIS) : null, prefixedWithThis ? TokenFactory.token3(TokenType.PERIOD) : null, identifier2(fieldName), TokenFactory.token3(TokenType.EQ), expression);
+  static ConstructorName constructorName(TypeName type, String name) => new ConstructorName.full(type, name == null ? null : TokenFactory.token3(TokenType.PERIOD), name == null ? null : identifier2(name));
+  static ContinueStatement continueStatement() => new ContinueStatement.full(TokenFactory.token(Keyword.CONTINUE), null, TokenFactory.token3(TokenType.SEMICOLON));
+  static ContinueStatement continueStatement2(String label) => new ContinueStatement.full(TokenFactory.token(Keyword.CONTINUE), identifier2(label), TokenFactory.token3(TokenType.SEMICOLON));
+  static DoStatement doStatement(Statement body, Expression condition) => new DoStatement.full(TokenFactory.token(Keyword.DO), body, TokenFactory.token(Keyword.WHILE), TokenFactory.token3(TokenType.OPEN_PAREN), condition, TokenFactory.token3(TokenType.CLOSE_PAREN), TokenFactory.token3(TokenType.SEMICOLON));
+  static DoubleLiteral doubleLiteral(double value) => new DoubleLiteral.full(TokenFactory.token2(value.toString()), value);
+  static EmptyFunctionBody emptyFunctionBody() => new EmptyFunctionBody.full(TokenFactory.token3(TokenType.SEMICOLON));
+  static EmptyStatement emptyStatement() => new EmptyStatement.full(TokenFactory.token3(TokenType.SEMICOLON));
+  static ExportDirective exportDirective(List<Annotation> metadata, String uri, List<Combinator> combinators) => new ExportDirective.full(null, metadata, TokenFactory.token(Keyword.EXPORT), string2(uri), list(combinators), TokenFactory.token3(TokenType.SEMICOLON));
+  static ExportDirective exportDirective2(String uri, List<Combinator> combinators) => exportDirective(new List<Annotation>(), uri, combinators);
+  static ExpressionFunctionBody expressionFunctionBody(Expression expression) => new ExpressionFunctionBody.full(TokenFactory.token3(TokenType.FUNCTION), expression, TokenFactory.token3(TokenType.SEMICOLON));
+  static ExpressionStatement expressionStatement(Expression expression) => new ExpressionStatement.full(expression, TokenFactory.token3(TokenType.SEMICOLON));
+  static ExtendsClause extendsClause(TypeName type) => new ExtendsClause.full(TokenFactory.token(Keyword.EXTENDS), type);
+  static FieldDeclaration fieldDeclaration(bool isStatic, Keyword keyword, TypeName type, List<VariableDeclaration> variables) => new FieldDeclaration.full(null, null, isStatic ? TokenFactory.token(Keyword.STATIC) : null, variableDeclarationList(keyword, type, variables), TokenFactory.token3(TokenType.SEMICOLON));
+  static FieldDeclaration fieldDeclaration2(bool isStatic, Keyword keyword, List<VariableDeclaration> variables) => fieldDeclaration(isStatic, keyword, null, variables);
+  static FieldFormalParameter fieldFormalParameter(Keyword keyword, TypeName type, String identifier) => new FieldFormalParameter.full(null, null, keyword == null ? null : TokenFactory.token(keyword), type, TokenFactory.token(Keyword.THIS), TokenFactory.token3(TokenType.PERIOD), identifier2(identifier));
+  static ForEachStatement forEachStatement(SimpleFormalParameter loopParameter, Expression iterator, Statement body) => new ForEachStatement.full(TokenFactory.token(Keyword.FOR), TokenFactory.token3(TokenType.OPEN_PAREN), loopParameter, TokenFactory.token(Keyword.IN), iterator, TokenFactory.token3(TokenType.CLOSE_PAREN), body);
+  static FormalParameterList formalParameterList(List<FormalParameter> parameters) => new FormalParameterList.full(TokenFactory.token3(TokenType.OPEN_PAREN), list(parameters), null, null, TokenFactory.token3(TokenType.CLOSE_PAREN));
+  static ForStatement forStatement(Expression initialization, Expression condition, List<Expression> updaters, Statement body) => new ForStatement.full(TokenFactory.token(Keyword.FOR), TokenFactory.token3(TokenType.OPEN_PAREN), null, initialization, TokenFactory.token3(TokenType.SEMICOLON), condition, TokenFactory.token3(TokenType.SEMICOLON), updaters, TokenFactory.token3(TokenType.CLOSE_PAREN), body);
+  static ForStatement forStatement2(VariableDeclarationList variableList, Expression condition, List<Expression> updaters, Statement body) => new ForStatement.full(TokenFactory.token(Keyword.FOR), TokenFactory.token3(TokenType.OPEN_PAREN), variableList, null, TokenFactory.token3(TokenType.SEMICOLON), condition, TokenFactory.token3(TokenType.SEMICOLON), updaters, TokenFactory.token3(TokenType.CLOSE_PAREN), body);
+  static FunctionDeclaration functionDeclaration(TypeName type, Keyword keyword, String name, FunctionExpression functionExpression) => new FunctionDeclaration.full(null, null, null, type, keyword == null ? null : TokenFactory.token(keyword), identifier2(name), functionExpression);
+  static FunctionDeclarationStatement functionDeclarationStatement(TypeName type, Keyword keyword, String name, FunctionExpression functionExpression) => new FunctionDeclarationStatement.full(functionDeclaration(type, keyword, name, functionExpression));
+  static FunctionExpression functionExpression() => new FunctionExpression.full(formalParameterList([]), blockFunctionBody([]));
+  static FunctionExpression functionExpression2(FormalParameterList parameters, FunctionBody body) => new FunctionExpression.full(parameters, body);
+  static FunctionExpressionInvocation functionExpressionInvocation(Expression function, List<Expression> arguments) => new FunctionExpressionInvocation.full(function, argumentList(arguments));
+  static FunctionTypedFormalParameter functionTypedFormalParameter(TypeName returnType, String identifier, List<FormalParameter> parameters) => new FunctionTypedFormalParameter.full(null, null, returnType, identifier2(identifier), formalParameterList(parameters));
+  static PrefixedIdentifier identifier(SimpleIdentifier prefix, SimpleIdentifier identifier8) => new PrefixedIdentifier.full(prefix, TokenFactory.token3(TokenType.PERIOD), identifier8);
+  static SimpleIdentifier identifier2(String lexeme) => new SimpleIdentifier.full(TokenFactory.token4(TokenType.IDENTIFIER, lexeme));
+  static PrefixedIdentifier identifier3(String prefix, SimpleIdentifier identifier) => new PrefixedIdentifier.full(identifier2(prefix), TokenFactory.token3(TokenType.PERIOD), identifier);
+  static PrefixedIdentifier identifier4(String prefix, String identifier) => new PrefixedIdentifier.full(identifier2(prefix), TokenFactory.token3(TokenType.PERIOD), identifier2(identifier));
+  static IfStatement ifStatement(Expression condition, Statement thenStatement) => ifStatement2(condition, thenStatement, null);
+  static IfStatement ifStatement2(Expression condition, Statement thenStatement, Statement elseStatement) => new IfStatement.full(TokenFactory.token(Keyword.IF), TokenFactory.token3(TokenType.OPEN_PAREN), condition, TokenFactory.token3(TokenType.CLOSE_PAREN), thenStatement, elseStatement == null ? null : TokenFactory.token(Keyword.ELSE), elseStatement);
+  static ImplementsClause implementsClause(List<TypeName> types) => new ImplementsClause.full(TokenFactory.token(Keyword.IMPLEMENTS), list(types));
+  static ImportDirective importDirective(List<Annotation> metadata, String uri, String prefix, List<Combinator> combinators) => new ImportDirective.full(null, metadata, TokenFactory.token(Keyword.IMPORT), string2(uri), prefix == null ? null : TokenFactory.token(Keyword.AS), prefix == null ? null : identifier2(prefix), list(combinators), TokenFactory.token3(TokenType.SEMICOLON));
+  static ImportDirective importDirective2(String uri, String prefix, List<Combinator> combinators) => importDirective(new List<Annotation>(), uri, prefix, combinators);
+  static HideCombinator importHideCombinator(List<SimpleIdentifier> identifiers) => new HideCombinator.full(TokenFactory.token2("hide"), list(identifiers));
+  static ShowCombinator importShowCombinator(List<SimpleIdentifier> identifiers) => new ShowCombinator.full(TokenFactory.token2("show"), list(identifiers));
+  static IndexExpression indexExpression(Expression array, Expression index) => new IndexExpression.forTarget_full(array, TokenFactory.token3(TokenType.OPEN_SQUARE_BRACKET), index, TokenFactory.token3(TokenType.CLOSE_SQUARE_BRACKET));
+  static InstanceCreationExpression instanceCreationExpression(Keyword keyword, TypeName type, List<Expression> arguments) => instanceCreationExpression2(keyword, type, null, arguments);
+  static InstanceCreationExpression instanceCreationExpression2(Keyword keyword, TypeName type, String identifier, List<Expression> arguments) => new InstanceCreationExpression.full(keyword == null ? null : TokenFactory.token(keyword), new ConstructorName.full(type, identifier == null ? null : TokenFactory.token3(TokenType.PERIOD), identifier == null ? null : identifier2(identifier)), argumentList(arguments));
+  static IntegerLiteral integer(int value) => new IntegerLiteral.full(TokenFactory.token4(TokenType.INT, value.toString()), value);
+  static InterpolationExpression interpolationExpression(Expression expression) => new InterpolationExpression.full(TokenFactory.token3(TokenType.STRING_INTERPOLATION_EXPRESSION), expression, TokenFactory.token3(TokenType.CLOSE_CURLY_BRACKET));
+  static InterpolationExpression interpolationExpression2(String identifier) => new InterpolationExpression.full(TokenFactory.token3(TokenType.STRING_INTERPOLATION_IDENTIFIER), identifier2(identifier), null);
+  static InterpolationString interpolationString(String contents, String value) => new InterpolationString.full(TokenFactory.token2(contents), value);
+  static IsExpression isExpression(Expression expression, bool negated, TypeName type) => new IsExpression.full(expression, TokenFactory.token(Keyword.IS), negated ? TokenFactory.token3(TokenType.BANG) : null, type);
+  static Label label(String label4) => new Label.full(identifier2(label4), TokenFactory.token3(TokenType.COLON));
+  static LabeledStatement labeledStatement(List<Label> labels, Statement statement) => new LabeledStatement.full(labels, statement);
+  static LibraryDirective libraryDirective(List<Annotation> metadata, LibraryIdentifier libraryName) => new LibraryDirective.full(null, metadata, TokenFactory.token(Keyword.LIBRARY), libraryName, TokenFactory.token3(TokenType.SEMICOLON));
+  static LibraryDirective libraryDirective2(String libraryName) => libraryDirective(new List<Annotation>(), libraryIdentifier2([libraryName]));
+  static LibraryIdentifier libraryIdentifier(List<SimpleIdentifier> components) => new LibraryIdentifier.full(list(components));
+  static LibraryIdentifier libraryIdentifier2(List<String> components) {
+    List<SimpleIdentifier> componentList = new List<SimpleIdentifier>();
+    for (String component in components) {
+      componentList.add(identifier2(component));
+    }
+    return new LibraryIdentifier.full(componentList);
+  }
+  static List<Object> list(List<Object> elements) {
+    List<Object> elementList = new List();
+    for (Object element in elements) {
+      elementList.add(element);
+    }
+    return elementList;
+  }
+  static ListLiteral listLiteral(List<Expression> elements) => listLiteral2(null, null, elements);
+  static ListLiteral listLiteral2(Keyword keyword, TypeArgumentList typeArguments, List<Expression> elements) => new ListLiteral.full(keyword == null ? null : TokenFactory.token(keyword), null, TokenFactory.token3(TokenType.OPEN_SQUARE_BRACKET), list(elements), TokenFactory.token3(TokenType.CLOSE_SQUARE_BRACKET));
+  static MapLiteral mapLiteral(Keyword keyword, TypeArgumentList typeArguments, List<MapLiteralEntry> entries) => new MapLiteral.full(keyword == null ? null : TokenFactory.token(keyword), typeArguments, TokenFactory.token3(TokenType.OPEN_CURLY_BRACKET), list(entries), TokenFactory.token3(TokenType.CLOSE_CURLY_BRACKET));
+  static MapLiteral mapLiteral2(List<MapLiteralEntry> entries) => mapLiteral(null, null, entries);
+  static MapLiteralEntry mapLiteralEntry(String key, Expression value) => new MapLiteralEntry.full(string2(key), TokenFactory.token3(TokenType.COLON), value);
+  static MethodDeclaration methodDeclaration(Keyword modifier, TypeName returnType, Keyword property, Keyword operator, Identifier name, FormalParameterList parameters) => new MethodDeclaration.full(null, null, TokenFactory.token(Keyword.EXTERNAL), modifier == null ? null : TokenFactory.token(modifier), returnType, property == null ? null : TokenFactory.token(property), operator == null ? null : TokenFactory.token(operator), name, parameters, emptyFunctionBody());
+  static MethodDeclaration methodDeclaration2(Keyword modifier, TypeName returnType, Keyword property, Keyword operator, Identifier name, FormalParameterList parameters, FunctionBody body) => new MethodDeclaration.full(null, null, null, modifier == null ? null : TokenFactory.token(modifier), returnType, property == null ? null : TokenFactory.token(property), operator == null ? null : TokenFactory.token(operator), name, parameters, body);
+  static MethodInvocation methodInvocation(Expression target, String methodName, List<Expression> arguments) => new MethodInvocation.full(target, target == null ? null : TokenFactory.token3(TokenType.PERIOD), identifier2(methodName), argumentList(arguments));
+  static MethodInvocation methodInvocation2(String methodName, List<Expression> arguments) => methodInvocation(null, methodName, arguments);
+  static NamedExpression namedExpression(String label5, Expression expression) => new NamedExpression.full(label(label5), expression);
+  static DefaultFormalParameter namedFormalParameter(NormalFormalParameter parameter, Expression expression) => new DefaultFormalParameter.full(parameter, ParameterKind.NAMED, expression == null ? null : TokenFactory.token3(TokenType.COLON), expression);
+  static NullLiteral nullLiteral() => new NullLiteral.full(TokenFactory.token(Keyword.NULL));
+  static ParenthesizedExpression parenthesizedExpression(Expression expression) => new ParenthesizedExpression.full(TokenFactory.token3(TokenType.OPEN_PAREN), expression, TokenFactory.token3(TokenType.CLOSE_PAREN));
+  static PartDirective partDirective(List<Annotation> metadata, String url) => new PartDirective.full(null, metadata, TokenFactory.token(Keyword.PART), string2(url), TokenFactory.token3(TokenType.SEMICOLON));
+  static PartDirective partDirective2(String url) => partDirective(new List<Annotation>(), url);
+  static PartOfDirective partOfDirective(LibraryIdentifier libraryName) => partOfDirective2(new List<Annotation>(), libraryName);
+  static PartOfDirective partOfDirective2(List<Annotation> metadata, LibraryIdentifier libraryName) => new PartOfDirective.full(null, metadata, TokenFactory.token(Keyword.PART), TokenFactory.token2("of"), libraryName, TokenFactory.token3(TokenType.SEMICOLON));
+  static DefaultFormalParameter positionalFormalParameter(NormalFormalParameter parameter, Expression expression) => new DefaultFormalParameter.full(parameter, ParameterKind.POSITIONAL, expression == null ? null : TokenFactory.token3(TokenType.EQ), expression);
+  static PostfixExpression postfixExpression(Expression expression, TokenType operator) => new PostfixExpression.full(expression, TokenFactory.token3(operator));
+  static PrefixExpression prefixExpression(TokenType operator, Expression expression) => new PrefixExpression.full(TokenFactory.token3(operator), expression);
+  static PropertyAccess propertyAccess(Expression target, String propertyName) => new PropertyAccess.full(target, TokenFactory.token3(TokenType.PERIOD), identifier2(propertyName));
+  static RedirectingConstructorInvocation redirectingConstructorInvocation(List<Expression> arguments) => redirectingConstructorInvocation2(null, arguments);
+  static RedirectingConstructorInvocation redirectingConstructorInvocation2(String constructorName, List<Expression> arguments) => new RedirectingConstructorInvocation.full(TokenFactory.token(Keyword.THIS), constructorName == null ? null : TokenFactory.token3(TokenType.PERIOD), constructorName == null ? null : identifier2(constructorName), argumentList(arguments));
+  static ReturnStatement returnStatement() => returnStatement2(null);
+  static ReturnStatement returnStatement2(Expression expression) => new ReturnStatement.full(TokenFactory.token(Keyword.RETURN), expression, TokenFactory.token3(TokenType.SEMICOLON));
+  static ScriptTag scriptTag(String scriptTag5) => new ScriptTag.full(TokenFactory.token2(scriptTag5));
+  static SimpleFormalParameter simpleFormalParameter(Keyword keyword, String parameterName) => simpleFormalParameter2(keyword, null, parameterName);
+  static SimpleFormalParameter simpleFormalParameter2(Keyword keyword, TypeName type, String parameterName) => new SimpleFormalParameter.full(null, null, keyword == null ? null : TokenFactory.token(keyword), type, identifier2(parameterName));
+  static SimpleFormalParameter simpleFormalParameter3(String parameterName) => simpleFormalParameter2(null, null, parameterName);
+  static SimpleFormalParameter simpleFormalParameter4(TypeName type, String parameterName) => simpleFormalParameter2(null, type, parameterName);
+  static StringInterpolation string(List<InterpolationElement> elements) => new StringInterpolation.full(list(elements));
+  static SimpleStringLiteral string2(String content) => new SimpleStringLiteral.full(TokenFactory.token2("'${content}'"), content);
+  static SuperConstructorInvocation superConstructorInvocation(List<Expression> arguments) => superConstructorInvocation2(null, arguments);
+  static SuperConstructorInvocation superConstructorInvocation2(String name, List<Expression> arguments) => new SuperConstructorInvocation.full(TokenFactory.token(Keyword.SUPER), name == null ? null : TokenFactory.token3(TokenType.PERIOD), name == null ? null : identifier2(name), argumentList(arguments));
+  static SuperExpression superExpression() => new SuperExpression.full(TokenFactory.token(Keyword.SUPER));
+  static SwitchCase switchCase(Expression expression, List<Statement> statements) => switchCase2(new List<Label>(), expression, statements);
+  static SwitchCase switchCase2(List<Label> labels, Expression expression, List<Statement> statements) => new SwitchCase.full(labels, TokenFactory.token(Keyword.CASE), expression, TokenFactory.token3(TokenType.COLON), list(statements));
+  static SwitchDefault switchDefault(List<Label> labels, List<Statement> statements) => new SwitchDefault.full(labels, TokenFactory.token(Keyword.DEFAULT), TokenFactory.token3(TokenType.COLON), list(statements));
+  static SwitchDefault switchDefault2(List<Statement> statements) => switchDefault(new List<Label>(), statements);
+  static SwitchStatement switchStatement(Expression expression, List<SwitchMember> members) => new SwitchStatement.full(TokenFactory.token(Keyword.SWITCH), TokenFactory.token3(TokenType.OPEN_PAREN), expression, TokenFactory.token3(TokenType.CLOSE_PAREN), TokenFactory.token3(TokenType.OPEN_CURLY_BRACKET), list(members), TokenFactory.token3(TokenType.CLOSE_CURLY_BRACKET));
+  static ThisExpression thisExpression() => new ThisExpression.full(TokenFactory.token(Keyword.THIS));
+  static ThrowExpression throwExpression() => throwExpression2(null);
+  static ThrowExpression throwExpression2(Expression expression) => new ThrowExpression.full(TokenFactory.token(Keyword.THROW), expression);
+  static TopLevelVariableDeclaration topLevelVariableDeclaration(Keyword keyword, TypeName type, List<VariableDeclaration> variables) => new TopLevelVariableDeclaration.full(null, null, variableDeclarationList(keyword, type, variables), TokenFactory.token3(TokenType.SEMICOLON));
+  static TopLevelVariableDeclaration topLevelVariableDeclaration2(Keyword keyword, List<VariableDeclaration> variables) => new TopLevelVariableDeclaration.full(null, null, variableDeclarationList(keyword, null, variables), TokenFactory.token3(TokenType.SEMICOLON));
+  static TryStatement tryStatement(Block body, Block finallyClause) => tryStatement3(body, new List<CatchClause>(), finallyClause);
+  static TryStatement tryStatement2(Block body, List<CatchClause> catchClauses) => tryStatement3(body, list(catchClauses), null);
+  static TryStatement tryStatement3(Block body, List<CatchClause> catchClauses, Block finallyClause) => new TryStatement.full(TokenFactory.token(Keyword.TRY), body, catchClauses, finallyClause == null ? null : TokenFactory.token(Keyword.FINALLY), finallyClause);
+  static FunctionTypeAlias typeAlias(TypeName returnType, String name, TypeParameterList typeParameters, FormalParameterList parameters) => new FunctionTypeAlias.full(null, null, TokenFactory.token(Keyword.TYPEDEF), returnType, identifier2(name), typeParameters, parameters, TokenFactory.token3(TokenType.SEMICOLON));
+  static TypeArgumentList typeArgumentList(List<TypeName> typeNames) => new TypeArgumentList.full(TokenFactory.token3(TokenType.LT), list(typeNames), TokenFactory.token3(TokenType.GT));
+  /**
+   * Create a type name whose name has been resolved to the given element and whose type has been
+   * resolved to the type of the given element.
+   * <p>
+   * <b>Note:</b> This method does not correctly handle class elements that have type parameters.
+   * @param element the element defining the type represented by the type name
+   * @return the type name that was created
+   */
+  static TypeName typeName(ClassElement element42, List<TypeName> arguments) {
+    SimpleIdentifier name19 = identifier2(element42.name);
+    name19.element = element42;
+    TypeName typeName = typeName2(name19, arguments);
+    typeName.type = element42.type;
+    return typeName;
+  }
+  static TypeName typeName2(Identifier name, List<TypeName> arguments) {
+    if (arguments.length == 0) {
+      return new TypeName.full(name, null);
+    }
+    return new TypeName.full(name, typeArgumentList(arguments));
+  }
+  static TypeName typeName3(String name, List<TypeName> arguments) {
+    if (arguments.length == 0) {
+      return new TypeName.full(identifier2(name), null);
+    }
+    return new TypeName.full(identifier2(name), typeArgumentList(arguments));
+  }
+  static TypeParameter typeParameter(String name) => new TypeParameter.full(null, null, identifier2(name), null, null);
+  static TypeParameter typeParameter2(String name, TypeName bound) => new TypeParameter.full(null, null, identifier2(name), TokenFactory.token(Keyword.EXTENDS), bound);
+  static TypeParameterList typeParameterList(List<String> typeNames) {
+    List<TypeParameter> typeParameters = new List<TypeParameter>();
+    for (String typeName in typeNames) {
+      typeParameters.add(typeParameter(typeName));
+    }
+    return new TypeParameterList.full(TokenFactory.token3(TokenType.LT), typeParameters, TokenFactory.token3(TokenType.GT));
+  }
+  static VariableDeclaration variableDeclaration(String name) => new VariableDeclaration.full(null, null, identifier2(name), null, null);
+  static VariableDeclaration variableDeclaration2(String name, Expression initializer) => new VariableDeclaration.full(null, null, identifier2(name), TokenFactory.token3(TokenType.EQ), initializer);
+  static VariableDeclarationList variableDeclarationList(Keyword keyword, TypeName type, List<VariableDeclaration> variables) => new VariableDeclarationList.full(keyword == null ? null : TokenFactory.token(keyword), type, list(variables));
+  static VariableDeclarationList variableDeclarationList2(Keyword keyword, List<VariableDeclaration> variables) => variableDeclarationList(keyword, null, variables);
+  static VariableDeclarationStatement variableDeclarationStatement(Keyword keyword, TypeName type, List<VariableDeclaration> variables) => new VariableDeclarationStatement.full(variableDeclarationList(keyword, type, variables), TokenFactory.token3(TokenType.SEMICOLON));
+  static VariableDeclarationStatement variableDeclarationStatement2(Keyword keyword, List<VariableDeclaration> variables) => variableDeclarationStatement(keyword, null, variables);
+  static WhileStatement whileStatement(Expression condition, Statement body) => new WhileStatement.full(TokenFactory.token(Keyword.WHILE), TokenFactory.token3(TokenType.OPEN_PAREN), condition, TokenFactory.token3(TokenType.CLOSE_PAREN), body);
+  static WithClause withClause(List<TypeName> types) => new WithClause.full(TokenFactory.token(Keyword.WITH), list(types));
+  /**
+   * Prevent the creation of instances of this class.
+   */
+  ASTFactory() {
+  }
+}
+class SimpleIdentifierTest extends ParserTestCase {
+  void test_inGetterContext_assignmentParent_notPure() {
+    SimpleIdentifier identifier = ASTFactory.identifier2("field");
+    ASTFactory.assignmentExpression(identifier, TokenType.PLUS_EQ, null);
+    JUnitTestCase.assertTrue(identifier.inGetterContext());
+  }
+  void test_inGetterContext_assignmentParent_pure() {
+    SimpleIdentifier identifier = ASTFactory.identifier2("field");
+    ASTFactory.assignmentExpression(identifier, TokenType.EQ, null);
+    JUnitTestCase.assertFalse(identifier.inGetterContext());
+  }
+  void test_inGetterContext_notAssignmentParent() {
+    SimpleIdentifier identifier = ASTFactory.identifier2("field");
+    ASTFactory.binaryExpression(identifier, TokenType.PLUS, null);
+    JUnitTestCase.assertTrue(identifier.inGetterContext());
+  }
+  void test_inGetterContext_qualifier() {
+    SimpleIdentifier identifier = ASTFactory.identifier2("field");
+    ASTFactory.identifier(identifier, null);
+    JUnitTestCase.assertTrue(identifier.inGetterContext());
+  }
+  void test_inGetterContext_whenQualified_false() {
+    SimpleIdentifier identifier = ASTFactory.identifier2("field");
+    PrefixedIdentifier prefixedIdentifier = ASTFactory.identifier3("myPrefix", identifier);
+    ASTFactory.assignmentExpression(prefixedIdentifier, TokenType.PLUS_EQ, null);
+    JUnitTestCase.assertTrue(identifier.inGetterContext());
+  }
+  void test_inGetterContext_whenQualified_true() {
+    SimpleIdentifier identifier = ASTFactory.identifier2("field");
+    PrefixedIdentifier prefixedIdentifier = ASTFactory.identifier3("myPrefix", identifier);
+    ASTFactory.assignmentExpression(prefixedIdentifier, TokenType.EQ, null);
+    JUnitTestCase.assertFalse(identifier.inGetterContext());
+  }
+  void test_inSetterContext_assignmentParent_leftEq() {
+    SimpleIdentifier identifier = ASTFactory.identifier2("field");
+    ASTFactory.assignmentExpression(identifier, TokenType.EQ, null);
+    JUnitTestCase.assertTrue(identifier.inSetterContext());
+  }
+  void test_inSetterContext_assignmentParent_leftPlusEq() {
+    SimpleIdentifier identifier = ASTFactory.identifier2("field");
+    ASTFactory.assignmentExpression(identifier, TokenType.PLUS_EQ, null);
+    JUnitTestCase.assertTrue(identifier.inSetterContext());
+  }
+  void test_inSetterContext_assignmentParent_rightEq() {
+    SimpleIdentifier identifier = ASTFactory.identifier2("field");
+    ASTFactory.assignmentExpression(null, TokenType.EQ, identifier);
+    JUnitTestCase.assertFalse(identifier.inSetterContext());
+  }
+  void test_inSetterContext_assignmentParent_rightPlusEq() {
+    SimpleIdentifier identifier = ASTFactory.identifier2("field");
+    ASTFactory.assignmentExpression(null, TokenType.PLUS_EQ, identifier);
+    JUnitTestCase.assertFalse(identifier.inSetterContext());
+  }
+  void test_inSetterContext_notInterestingParent() {
+    SimpleIdentifier identifier = ASTFactory.identifier2("field");
+    ASTFactory.binaryExpression(identifier, null, null);
+    JUnitTestCase.assertFalse(identifier.inSetterContext());
+  }
+  void test_inSetterContext_postfixParent() {
+    SimpleIdentifier identifier = ASTFactory.identifier2("field");
+    ASTFactory.postfixExpression(identifier, null);
+    JUnitTestCase.assertTrue(identifier.inSetterContext());
+  }
+  void test_inSetterContext_prefixParent_bang() {
+    SimpleIdentifier identifier = ASTFactory.identifier2("field");
+    ASTFactory.prefixExpression(TokenType.BANG, identifier);
+    JUnitTestCase.assertFalse(identifier.inSetterContext());
+  }
+  void test_inSetterContext_prefixParent_minusMinus() {
+    SimpleIdentifier identifier = ASTFactory.identifier2("field");
+    ASTFactory.prefixExpression(TokenType.MINUS_MINUS, identifier);
+    JUnitTestCase.assertTrue(identifier.inSetterContext());
+  }
+  void test_inSetterContext_prefixParent_plusPlus() {
+    SimpleIdentifier identifier = ASTFactory.identifier2("field");
+    ASTFactory.prefixExpression(TokenType.PLUS_PLUS, identifier);
+    JUnitTestCase.assertTrue(identifier.inSetterContext());
+  }
+  void test_inSetterContext_qualifier() {
+    SimpleIdentifier identifier = ASTFactory.identifier2("field");
+    ASTFactory.identifier(identifier, null);
+    JUnitTestCase.assertFalse(identifier.inSetterContext());
+  }
+  void test_inSetterContext_whenQualified_prefixParent_bang() {
+    SimpleIdentifier identifier = ASTFactory.identifier2("field");
+    PrefixedIdentifier prefixedIdentifier = ASTFactory.identifier3("myPrefix", identifier);
+    ASTFactory.prefixExpression(TokenType.BANG, prefixedIdentifier);
+    JUnitTestCase.assertFalse(identifier.inSetterContext());
+  }
+  void test_inSetterContext_whenQualified_prefixParent_plusPlus() {
+    SimpleIdentifier identifier = ASTFactory.identifier2("field");
+    PrefixedIdentifier prefixedIdentifier = ASTFactory.identifier3("myPrefix", identifier);
+    ASTFactory.prefixExpression(TokenType.PLUS_PLUS, prefixedIdentifier);
+    JUnitTestCase.assertTrue(identifier.inSetterContext());
+  }
+  static dartSuite() {
+    _ut.group('SimpleIdentifierTest', () {
+      _ut.test('test_inGetterContext_assignmentParent_notPure', () {
+        final __test = new SimpleIdentifierTest();
+        runJUnitTest(__test, __test.test_inGetterContext_assignmentParent_notPure);
+      });
+      _ut.test('test_inGetterContext_assignmentParent_pure', () {
+        final __test = new SimpleIdentifierTest();
+        runJUnitTest(__test, __test.test_inGetterContext_assignmentParent_pure);
+      });
+      _ut.test('test_inGetterContext_notAssignmentParent', () {
+        final __test = new SimpleIdentifierTest();
+        runJUnitTest(__test, __test.test_inGetterContext_notAssignmentParent);
+      });
+      _ut.test('test_inGetterContext_qualifier', () {
+        final __test = new SimpleIdentifierTest();
+        runJUnitTest(__test, __test.test_inGetterContext_qualifier);
+      });
+      _ut.test('test_inGetterContext_whenQualified_false', () {
+        final __test = new SimpleIdentifierTest();
+        runJUnitTest(__test, __test.test_inGetterContext_whenQualified_false);
+      });
+      _ut.test('test_inGetterContext_whenQualified_true', () {
+        final __test = new SimpleIdentifierTest();
+        runJUnitTest(__test, __test.test_inGetterContext_whenQualified_true);
+      });
+      _ut.test('test_inSetterContext_assignmentParent_leftEq', () {
+        final __test = new SimpleIdentifierTest();
+        runJUnitTest(__test, __test.test_inSetterContext_assignmentParent_leftEq);
+      });
+      _ut.test('test_inSetterContext_assignmentParent_leftPlusEq', () {
+        final __test = new SimpleIdentifierTest();
+        runJUnitTest(__test, __test.test_inSetterContext_assignmentParent_leftPlusEq);
+      });
+      _ut.test('test_inSetterContext_assignmentParent_rightEq', () {
+        final __test = new SimpleIdentifierTest();
+        runJUnitTest(__test, __test.test_inSetterContext_assignmentParent_rightEq);
+      });
+      _ut.test('test_inSetterContext_assignmentParent_rightPlusEq', () {
+        final __test = new SimpleIdentifierTest();
+        runJUnitTest(__test, __test.test_inSetterContext_assignmentParent_rightPlusEq);
+      });
+      _ut.test('test_inSetterContext_notInterestingParent', () {
+        final __test = new SimpleIdentifierTest();
+        runJUnitTest(__test, __test.test_inSetterContext_notInterestingParent);
+      });
+      _ut.test('test_inSetterContext_postfixParent', () {
+        final __test = new SimpleIdentifierTest();
+        runJUnitTest(__test, __test.test_inSetterContext_postfixParent);
+      });
+      _ut.test('test_inSetterContext_prefixParent_bang', () {
+        final __test = new SimpleIdentifierTest();
+        runJUnitTest(__test, __test.test_inSetterContext_prefixParent_bang);
+      });
+      _ut.test('test_inSetterContext_prefixParent_minusMinus', () {
+        final __test = new SimpleIdentifierTest();
+        runJUnitTest(__test, __test.test_inSetterContext_prefixParent_minusMinus);
+      });
+      _ut.test('test_inSetterContext_prefixParent_plusPlus', () {
+        final __test = new SimpleIdentifierTest();
+        runJUnitTest(__test, __test.test_inSetterContext_prefixParent_plusPlus);
+      });
+      _ut.test('test_inSetterContext_qualifier', () {
+        final __test = new SimpleIdentifierTest();
+        runJUnitTest(__test, __test.test_inSetterContext_qualifier);
+      });
+      _ut.test('test_inSetterContext_whenQualified_prefixParent_bang', () {
+        final __test = new SimpleIdentifierTest();
+        runJUnitTest(__test, __test.test_inSetterContext_whenQualified_prefixParent_bang);
+      });
+      _ut.test('test_inSetterContext_whenQualified_prefixParent_plusPlus', () {
+        final __test = new SimpleIdentifierTest();
+        runJUnitTest(__test, __test.test_inSetterContext_whenQualified_prefixParent_plusPlus);
+      });
+    });
+  }
+}
+class ToSourceVisitorTest extends EngineTestCase {
+  void test_visitAdjacentStrings() {
+    assertSource("'a' 'b'", ASTFactory.adjacentStrings([ASTFactory.string2("a"), ASTFactory.string2("b")]));
+  }
+  void test_visitAnnotation_constant() {
+    assertSource("@A", ASTFactory.annotation(ASTFactory.identifier2("A")));
+  }
+  void test_visitAnnotation_constructor() {
+    assertSource("@A.c()", ASTFactory.annotation2(ASTFactory.identifier2("A"), ASTFactory.identifier2("c"), ASTFactory.argumentList([])));
+  }
+  void test_visitArgumentDefinitionTest() {
+    assertSource("?a", ASTFactory.argumentDefinitionTest("a"));
+  }
+  void test_visitArgumentList() {
+    assertSource("(a, b)", ASTFactory.argumentList([ASTFactory.identifier2("a"), ASTFactory.identifier2("b")]));
+  }
+  void test_visitAsExpression() {
+    assertSource("e as T", ASTFactory.asExpression(ASTFactory.identifier2("e"), ASTFactory.typeName3("T", [])));
+  }
+  void test_visitAssertStatement() {
+    assertSource("assert (a);", ASTFactory.assertStatement(ASTFactory.identifier2("a")));
+  }
+  void test_visitAssignmentExpression() {
+    assertSource("a = b", ASTFactory.assignmentExpression(ASTFactory.identifier2("a"), TokenType.EQ, ASTFactory.identifier2("b")));
+  }
+  void test_visitBinaryExpression() {
+    assertSource("a + b", ASTFactory.binaryExpression(ASTFactory.identifier2("a"), TokenType.PLUS, ASTFactory.identifier2("b")));
+  }
+  void test_visitBlock_empty() {
+    assertSource("{}", ASTFactory.block([]));
+  }
+  void test_visitBlock_nonEmpty() {
+    assertSource("{break; break;}", ASTFactory.block([ASTFactory.breakStatement(), ASTFactory.breakStatement()]));
+  }
+  void test_visitBlockFunctionBody() {
+    assertSource("{}", ASTFactory.blockFunctionBody([]));
+  }
+  void test_visitBooleanLiteral_false() {
+    assertSource("false", ASTFactory.booleanLiteral(false));
+  }
+  void test_visitBooleanLiteral_true() {
+    assertSource("true", ASTFactory.booleanLiteral(true));
+  }
+  void test_visitBreakStatement_label() {
+    assertSource("break l;", ASTFactory.breakStatement2("l"));
+  }
+  void test_visitBreakStatement_noLabel() {
+    assertSource("break;", ASTFactory.breakStatement());
+  }
+  void test_visitCascadeExpression_field() {
+    assertSource("a..b..c", ASTFactory.cascadeExpression(ASTFactory.identifier2("a"), [ASTFactory.cascadedPropertyAccess("b"), ASTFactory.cascadedPropertyAccess("c")]));
+  }
+  void test_visitCascadeExpression_index() {
+    assertSource("a..[0]..[1]", ASTFactory.cascadeExpression(ASTFactory.identifier2("a"), [ASTFactory.cascadedIndexExpression(ASTFactory.integer(0)), ASTFactory.cascadedIndexExpression(ASTFactory.integer(1))]));
+  }
+  void test_visitCascadeExpression_method() {
+    assertSource("a..b()..c()", ASTFactory.cascadeExpression(ASTFactory.identifier2("a"), [ASTFactory.cascadedMethodInvocation("b", []), ASTFactory.cascadedMethodInvocation("c", [])]));
+  }
+  void test_visitCatchClause_catch_noStack() {
+    assertSource("catch (e) {}", ASTFactory.catchClause("e", []));
+  }
+  void test_visitCatchClause_catch_stack() {
+    assertSource("catch (e, s) {}", ASTFactory.catchClause2("e", "s", []));
+  }
+  void test_visitCatchClause_on() {
+    assertSource("on E {}", ASTFactory.catchClause3(ASTFactory.typeName3("E", []), []));
+  }
+  void test_visitCatchClause_on_catch() {
+    assertSource("on E catch (e) {}", ASTFactory.catchClause4(ASTFactory.typeName3("E", []), "e", []));
+  }
+  void test_visitClassDeclaration_abstract() {
+    assertSource("abstract class C {}", ASTFactory.classDeclaration(Keyword.ABSTRACT, "C", null, null, null, null, []));
+  }
+  void test_visitClassDeclaration_empty() {
+    assertSource("class C {}", ASTFactory.classDeclaration(null, "C", null, null, null, null, []));
+  }
+  void test_visitClassDeclaration_extends() {
+    assertSource("class C extends A {}", ASTFactory.classDeclaration(null, "C", null, ASTFactory.extendsClause(ASTFactory.typeName3("A", [])), null, null, []));
+  }
+  void test_visitClassDeclaration_extends_implements() {
+    assertSource("class C extends A implements B {}", ASTFactory.classDeclaration(null, "C", null, ASTFactory.extendsClause(ASTFactory.typeName3("A", [])), null, ASTFactory.implementsClause([ASTFactory.typeName3("B", [])]), []));
+  }
+  void test_visitClassDeclaration_extends_with() {
+    assertSource("class C extends A with M {}", ASTFactory.classDeclaration(null, "C", null, ASTFactory.extendsClause(ASTFactory.typeName3("A", [])), ASTFactory.withClause([ASTFactory.typeName3("M", [])]), null, []));
+  }
+  void test_visitClassDeclaration_extends_with_implements() {
+    assertSource("class C extends A with M implements B {}", ASTFactory.classDeclaration(null, "C", null, ASTFactory.extendsClause(ASTFactory.typeName3("A", [])), ASTFactory.withClause([ASTFactory.typeName3("M", [])]), ASTFactory.implementsClause([ASTFactory.typeName3("B", [])]), []));
+  }
+  void test_visitClassDeclaration_implements() {
+    assertSource("class C implements B {}", ASTFactory.classDeclaration(null, "C", null, null, null, ASTFactory.implementsClause([ASTFactory.typeName3("B", [])]), []));
+  }
+  void test_visitClassDeclaration_multipleMember() {
+    assertSource("class C {var a; var b;}", ASTFactory.classDeclaration(null, "C", null, null, null, null, [ASTFactory.fieldDeclaration2(false, Keyword.VAR, [ASTFactory.variableDeclaration("a")]), ASTFactory.fieldDeclaration2(false, Keyword.VAR, [ASTFactory.variableDeclaration("b")])]));
+  }
+  void test_visitClassDeclaration_parameters() {
+    assertSource("class C<E> {}", ASTFactory.classDeclaration(null, "C", ASTFactory.typeParameterList(["E"]), null, null, null, []));
+  }
+  void test_visitClassDeclaration_parameters_extends() {
+    assertSource("class C<E> extends A {}", ASTFactory.classDeclaration(null, "C", ASTFactory.typeParameterList(["E"]), ASTFactory.extendsClause(ASTFactory.typeName3("A", [])), null, null, []));
+  }
+  void test_visitClassDeclaration_parameters_extends_implements() {
+    assertSource("class C<E> extends A implements B {}", ASTFactory.classDeclaration(null, "C", ASTFactory.typeParameterList(["E"]), ASTFactory.extendsClause(ASTFactory.typeName3("A", [])), null, ASTFactory.implementsClause([ASTFactory.typeName3("B", [])]), []));
+  }
+  void test_visitClassDeclaration_parameters_extends_with() {
+    assertSource("class C<E> extends A with M {}", ASTFactory.classDeclaration(null, "C", ASTFactory.typeParameterList(["E"]), ASTFactory.extendsClause(ASTFactory.typeName3("A", [])), ASTFactory.withClause([ASTFactory.typeName3("M", [])]), null, []));
+  }
+  void test_visitClassDeclaration_parameters_extends_with_implements() {
+    assertSource("class C<E> extends A with M implements B {}", ASTFactory.classDeclaration(null, "C", ASTFactory.typeParameterList(["E"]), ASTFactory.extendsClause(ASTFactory.typeName3("A", [])), ASTFactory.withClause([ASTFactory.typeName3("M", [])]), ASTFactory.implementsClause([ASTFactory.typeName3("B", [])]), []));
+  }
+  void test_visitClassDeclaration_parameters_implements() {
+    assertSource("class C<E> implements B {}", ASTFactory.classDeclaration(null, "C", ASTFactory.typeParameterList(["E"]), null, null, ASTFactory.implementsClause([ASTFactory.typeName3("B", [])]), []));
+  }
+  void test_visitClassDeclaration_singleMember() {
+    assertSource("class C {var a;}", ASTFactory.classDeclaration(null, "C", null, null, null, null, [ASTFactory.fieldDeclaration2(false, Keyword.VAR, [ASTFactory.variableDeclaration("a")])]));
+  }
+  void test_visitClassTypeAlias_abstract() {
+    assertSource("typedef C = abstract S with M1;", ASTFactory.classTypeAlias("C", null, Keyword.ABSTRACT, ASTFactory.typeName3("S", []), ASTFactory.withClause([ASTFactory.typeName3("M1", [])]), null));
+  }
+  void test_visitClassTypeAlias_abstract_implements() {
+    assertSource("typedef C = abstract S with M1 implements I;", ASTFactory.classTypeAlias("C", null, Keyword.ABSTRACT, ASTFactory.typeName3("S", []), ASTFactory.withClause([ASTFactory.typeName3("M1", [])]), ASTFactory.implementsClause([ASTFactory.typeName3("I", [])])));
+  }
+  void test_visitClassTypeAlias_generic() {
+    assertSource("typedef C<E> = S<E> with M1<E>;", ASTFactory.classTypeAlias("C", ASTFactory.typeParameterList(["E"]), null, ASTFactory.typeName3("S", [ASTFactory.typeName3("E", [])]), ASTFactory.withClause([ASTFactory.typeName3("M1", [ASTFactory.typeName3("E", [])])]), null));
+  }
+  void test_visitClassTypeAlias_implements() {
+    assertSource("typedef C = S with M1 implements I;", ASTFactory.classTypeAlias("C", null, null, ASTFactory.typeName3("S", []), ASTFactory.withClause([ASTFactory.typeName3("M1", [])]), ASTFactory.implementsClause([ASTFactory.typeName3("I", [])])));
+  }
+  void test_visitClassTypeAlias_minimal() {
+    assertSource("typedef C = S with M1;", ASTFactory.classTypeAlias("C", null, null, ASTFactory.typeName3("S", []), ASTFactory.withClause([ASTFactory.typeName3("M1", [])]), null));
+  }
+  void test_visitClassTypeAlias_parameters_abstract() {
+    assertSource("typedef C<E> = abstract S with M1;", ASTFactory.classTypeAlias("C", ASTFactory.typeParameterList(["E"]), Keyword.ABSTRACT, ASTFactory.typeName3("S", []), ASTFactory.withClause([ASTFactory.typeName3("M1", [])]), null));
+  }
+  void test_visitClassTypeAlias_parameters_abstract_implements() {
+    assertSource("typedef C<E> = abstract S with M1 implements I;", ASTFactory.classTypeAlias("C", ASTFactory.typeParameterList(["E"]), Keyword.ABSTRACT, ASTFactory.typeName3("S", []), ASTFactory.withClause([ASTFactory.typeName3("M1", [])]), ASTFactory.implementsClause([ASTFactory.typeName3("I", [])])));
+  }
+  void test_visitClassTypeAlias_parameters_implements() {
+    assertSource("typedef C<E> = S with M1 implements I;", ASTFactory.classTypeAlias("C", ASTFactory.typeParameterList(["E"]), null, ASTFactory.typeName3("S", []), ASTFactory.withClause([ASTFactory.typeName3("M1", [])]), ASTFactory.implementsClause([ASTFactory.typeName3("I", [])])));
+  }
+  void test_visitComment() {
+    assertSource("", Comment.createBlockComment(<Token> [TokenFactory.token2("/* comment */")]));
+  }
+  void test_visitCommentReference() {
+    assertSource("", new CommentReference.full(null, ASTFactory.identifier2("a")));
+  }
+  void test_visitCompilationUnit_declaration() {
+    assertSource("var a;", ASTFactory.compilationUnit2([ASTFactory.topLevelVariableDeclaration2(Keyword.VAR, [ASTFactory.variableDeclaration("a")])]));
+  }
+  void test_visitCompilationUnit_directive() {
+    assertSource("library l;", ASTFactory.compilationUnit3([ASTFactory.libraryDirective2("l")]));
+  }
+  void test_visitCompilationUnit_directive_declaration() {
+    assertSource("library l; var a;", ASTFactory.compilationUnit4(ASTFactory.list([(ASTFactory.libraryDirective2("l") as Directive)]), ASTFactory.list([(ASTFactory.topLevelVariableDeclaration2(Keyword.VAR, [ASTFactory.variableDeclaration("a")]) as CompilationUnitMember)])));
+  }
+  void test_visitCompilationUnit_empty() {
+    assertSource("", ASTFactory.compilationUnit());
+  }
+  void test_visitCompilationUnit_script() {
+    assertSource("!#/bin/dartvm", ASTFactory.compilationUnit5("!#/bin/dartvm"));
+  }
+  void test_visitCompilationUnit_script_declaration() {
+    assertSource("!#/bin/dartvm var a;", ASTFactory.compilationUnit6("!#/bin/dartvm", [ASTFactory.topLevelVariableDeclaration2(Keyword.VAR, [ASTFactory.variableDeclaration("a")])]));
+  }
+  void test_visitCompilationUnit_script_directive() {
+    assertSource("!#/bin/dartvm library l;", ASTFactory.compilationUnit7("!#/bin/dartvm", [ASTFactory.libraryDirective2("l")]));
+  }
+  void test_visitCompilationUnit_script_directives_declarations() {
+    assertSource("!#/bin/dartvm library l; var a;", ASTFactory.compilationUnit8("!#/bin/dartvm", ASTFactory.list([(ASTFactory.libraryDirective2("l") as Directive)]), ASTFactory.list([(ASTFactory.topLevelVariableDeclaration2(Keyword.VAR, [ASTFactory.variableDeclaration("a")]) as CompilationUnitMember)])));
+  }
+  void test_visitConditionalExpression() {
+    assertSource("a ? b : c", ASTFactory.conditionalExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"), ASTFactory.identifier2("c")));
+  }
+  void test_visitConstructorDeclaration_const() {
+    assertSource("const C() {}", ASTFactory.constructorDeclaration2(Keyword.CONST, null, ASTFactory.identifier2("C"), null, ASTFactory.formalParameterList([]), null, ASTFactory.blockFunctionBody([])));
+  }
+  void test_visitConstructorDeclaration_external() {
+    assertSource("external C();", ASTFactory.constructorDeclaration(ASTFactory.identifier2("C"), null, ASTFactory.formalParameterList([]), null));
+  }
+  void test_visitConstructorDeclaration_minimal() {
+    assertSource("C() {}", ASTFactory.constructorDeclaration2(null, null, ASTFactory.identifier2("C"), null, ASTFactory.formalParameterList([]), null, ASTFactory.blockFunctionBody([])));
+  }
+  void test_visitConstructorDeclaration_multipleInitializers() {
+    assertSource("C() : a = b, c = d {}", ASTFactory.constructorDeclaration2(null, null, ASTFactory.identifier2("C"), null, ASTFactory.formalParameterList([]), ASTFactory.list([(ASTFactory.constructorFieldInitializer(false, "a", ASTFactory.identifier2("b")) as ConstructorInitializer), ASTFactory.constructorFieldInitializer(false, "c", ASTFactory.identifier2("d"))]), ASTFactory.blockFunctionBody([])));
+  }
+  void test_visitConstructorDeclaration_multipleParameters() {
+    assertSource("C(var a, var b) {}", ASTFactory.constructorDeclaration2(null, null, ASTFactory.identifier2("C"), null, ASTFactory.formalParameterList([ASTFactory.simpleFormalParameter(Keyword.VAR, "a"), ASTFactory.simpleFormalParameter(Keyword.VAR, "b")]), null, ASTFactory.blockFunctionBody([])));
+  }
+  void test_visitConstructorDeclaration_named() {
+    assertSource("C.m() {}", ASTFactory.constructorDeclaration2(null, null, ASTFactory.identifier2("C"), "m", ASTFactory.formalParameterList([]), null, ASTFactory.blockFunctionBody([])));
+  }
+  void test_visitConstructorDeclaration_singleInitializer() {
+    assertSource("C() : a = b {}", ASTFactory.constructorDeclaration2(null, null, ASTFactory.identifier2("C"), null, ASTFactory.formalParameterList([]), ASTFactory.list([(ASTFactory.constructorFieldInitializer(false, "a", ASTFactory.identifier2("b")) as ConstructorInitializer)]), ASTFactory.blockFunctionBody([])));
+  }
+  void test_visitConstructorFieldInitializer_withoutThis() {
+    assertSource("a = b", ASTFactory.constructorFieldInitializer(false, "a", ASTFactory.identifier2("b")));
+  }
+  void test_visitConstructorFieldInitializer_withThis() {
+    assertSource("this.a = b", ASTFactory.constructorFieldInitializer(true, "a", ASTFactory.identifier2("b")));
+  }
+  void test_visitConstructorName_named_prefix() {
+    assertSource("p.C.n", ASTFactory.constructorName(ASTFactory.typeName3("p.C.n", []), null));
+  }
+  void test_visitConstructorName_unnamed_noPrefix() {
+    assertSource("C", ASTFactory.constructorName(ASTFactory.typeName3("C", []), null));
+  }
+  void test_visitConstructorName_unnamed_prefix() {
+    assertSource("p.C", ASTFactory.constructorName(ASTFactory.typeName2(ASTFactory.identifier4("p", "C"), []), null));
+  }
+  void test_visitContinueStatement_label() {
+    assertSource("continue l;", ASTFactory.continueStatement2("l"));
+  }
+  void test_visitContinueStatement_noLabel() {
+    assertSource("continue;", ASTFactory.continueStatement());
+  }
+  void test_visitDefaultFormalParameter_named_noValue() {
+    assertSource("p", ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("p"), null));
+  }
+  void test_visitDefaultFormalParameter_named_value() {
+    assertSource("p : 0", ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("p"), ASTFactory.integer(0)));
+  }
+  void test_visitDefaultFormalParameter_positional_noValue() {
+    assertSource("p", ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("p"), null));
+  }
+  void test_visitDefaultFormalParameter_positional_value() {
+    assertSource("p = 0", ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("p"), ASTFactory.integer(0)));
+  }
+  void test_visitDoStatement() {
+    assertSource("do {} while (c);", ASTFactory.doStatement(ASTFactory.block([]), ASTFactory.identifier2("c")));
+  }
+  void test_visitDoubleLiteral() {
+    assertSource("4.2", ASTFactory.doubleLiteral(4.2));
+  }
+  void test_visitEmptyFunctionBody() {
+    assertSource(";", ASTFactory.emptyFunctionBody());
+  }
+  void test_visitEmptyStatement() {
+    assertSource(";", ASTFactory.emptyStatement());
+  }
+  void test_visitExportDirective_combinator() {
+    assertSource("export 'a.dart' show A;", ASTFactory.exportDirective2("a.dart", [(ASTFactory.importShowCombinator([ASTFactory.identifier2("A")]) as Combinator)]));
+  }
+  void test_visitExportDirective_combinators() {
+    assertSource("export 'a.dart' show A hide B;", ASTFactory.exportDirective2("a.dart", [ASTFactory.importShowCombinator([ASTFactory.identifier2("A")]), ASTFactory.importHideCombinator([ASTFactory.identifier2("B")])]));
+  }
+  void test_visitExportDirective_minimal() {
+    assertSource("export 'a.dart';", ASTFactory.exportDirective2("a.dart", []));
+  }
+  void test_visitExpressionFunctionBody() {
+    assertSource("=> a;", ASTFactory.expressionFunctionBody(ASTFactory.identifier2("a")));
+  }
+  void test_visitExpressionStatement() {
+    assertSource("a;", ASTFactory.expressionStatement(ASTFactory.identifier2("a")));
+  }
+  void test_visitExtendsClause() {
+    assertSource("extends C", ASTFactory.extendsClause(ASTFactory.typeName3("C", [])));
+  }
+  void test_visitFieldDeclaration_instance() {
+    assertSource("var a;", ASTFactory.fieldDeclaration2(false, Keyword.VAR, [ASTFactory.variableDeclaration("a")]));
+  }
+  void test_visitFieldDeclaration_static() {
+    assertSource("static var a;", ASTFactory.fieldDeclaration2(true, Keyword.VAR, [ASTFactory.variableDeclaration("a")]));
+  }
+  void test_visitFieldFormalParameter_keyword() {
+    assertSource("var this.a", ASTFactory.fieldFormalParameter(Keyword.VAR, null, "a"));
+  }
+  void test_visitFieldFormalParameter_keywordAndType() {
+    assertSource("final A this.a", ASTFactory.fieldFormalParameter(Keyword.FINAL, ASTFactory.typeName3("A", []), "a"));
+  }
+  void test_visitFieldFormalParameter_type() {
+    assertSource("A this.a", ASTFactory.fieldFormalParameter(null, ASTFactory.typeName3("A", []), "a"));
+  }
+  void test_visitForEachStatement() {
+    assertSource("for (a in b) {}", ASTFactory.forEachStatement(ASTFactory.simpleFormalParameter3("a"), ASTFactory.identifier2("b"), ASTFactory.block([])));
+  }
+  void test_visitFormalParameterList_empty() {
+    assertSource("()", ASTFactory.formalParameterList([]));
+  }
+  void test_visitFormalParameterList_n() {
+    assertSource("({a : 0})", ASTFactory.formalParameterList([ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("a"), ASTFactory.integer(0))]));
+  }
+  void test_visitFormalParameterList_nn() {
+    assertSource("({a : 0, b : 1})", ASTFactory.formalParameterList([ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("a"), ASTFactory.integer(0)), ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("b"), ASTFactory.integer(1))]));
+  }
+  void test_visitFormalParameterList_p() {
+    assertSource("([a = 0])", ASTFactory.formalParameterList([ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("a"), ASTFactory.integer(0))]));
+  }
+  void test_visitFormalParameterList_pp() {
+    assertSource("([a = 0, b = 1])", ASTFactory.formalParameterList([ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("a"), ASTFactory.integer(0)), ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("b"), ASTFactory.integer(1))]));
+  }
+  void test_visitFormalParameterList_r() {
+    assertSource("(a)", ASTFactory.formalParameterList([ASTFactory.simpleFormalParameter3("a")]));
+  }
+  void test_visitFormalParameterList_rn() {
+    assertSource("(a, {b : 1})", ASTFactory.formalParameterList([ASTFactory.simpleFormalParameter3("a"), ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("b"), ASTFactory.integer(1))]));
+  }
+  void test_visitFormalParameterList_rnn() {
+    assertSource("(a, {b : 1, c : 2})", ASTFactory.formalParameterList([ASTFactory.simpleFormalParameter3("a"), ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("b"), ASTFactory.integer(1)), ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("c"), ASTFactory.integer(2))]));
+  }
+  void test_visitFormalParameterList_rp() {
+    assertSource("(a, [b = 1])", ASTFactory.formalParameterList([ASTFactory.simpleFormalParameter3("a"), ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("b"), ASTFactory.integer(1))]));
+  }
+  void test_visitFormalParameterList_rpp() {
+    assertSource("(a, [b = 1, c = 2])", ASTFactory.formalParameterList([ASTFactory.simpleFormalParameter3("a"), ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("b"), ASTFactory.integer(1)), ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("c"), ASTFactory.integer(2))]));
+  }
+  void test_visitFormalParameterList_rr() {
+    assertSource("(a, b)", ASTFactory.formalParameterList([ASTFactory.simpleFormalParameter3("a"), ASTFactory.simpleFormalParameter3("b")]));
+  }
+  void test_visitFormalParameterList_rrn() {
+    assertSource("(a, b, {c : 3})", ASTFactory.formalParameterList([ASTFactory.simpleFormalParameter3("a"), ASTFactory.simpleFormalParameter3("b"), ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("c"), ASTFactory.integer(3))]));
+  }
+  void test_visitFormalParameterList_rrnn() {
+    assertSource("(a, b, {c : 3, d : 4})", ASTFactory.formalParameterList([ASTFactory.simpleFormalParameter3("a"), ASTFactory.simpleFormalParameter3("b"), ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("c"), ASTFactory.integer(3)), ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter3("d"), ASTFactory.integer(4))]));
+  }
+  void test_visitFormalParameterList_rrp() {
+    assertSource("(a, b, [c = 3])", ASTFactory.formalParameterList([ASTFactory.simpleFormalParameter3("a"), ASTFactory.simpleFormalParameter3("b"), ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("c"), ASTFactory.integer(3))]));
+  }
+  void test_visitFormalParameterList_rrpp() {
+    assertSource("(a, b, [c = 3, d = 4])", ASTFactory.formalParameterList([ASTFactory.simpleFormalParameter3("a"), ASTFactory.simpleFormalParameter3("b"), ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("c"), ASTFactory.integer(3)), ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter3("d"), ASTFactory.integer(4))]));
+  }
+  void test_visitForStatement_c() {
+    assertSource("for (; c;) {}", ASTFactory.forStatement((null as Expression), ASTFactory.identifier2("c"), null, ASTFactory.block([])));
+  }
+  void test_visitForStatement_cu() {
+    assertSource("for (; c; u) {}", ASTFactory.forStatement((null as Expression), ASTFactory.identifier2("c"), ASTFactory.list([(ASTFactory.identifier2("u") as Expression)]), ASTFactory.block([])));
+  }
+  void test_visitForStatement_e() {
+    assertSource("for (e;;) {}", ASTFactory.forStatement(ASTFactory.identifier2("e"), null, null, ASTFactory.block([])));
+  }
+  void test_visitForStatement_ec() {
+    assertSource("for (e; c;) {}", ASTFactory.forStatement(ASTFactory.identifier2("e"), ASTFactory.identifier2("c"), null, ASTFactory.block([])));
+  }
+  void test_visitForStatement_ecu() {
+    assertSource("for (e; c; u) {}", ASTFactory.forStatement(ASTFactory.identifier2("e"), ASTFactory.identifier2("c"), ASTFactory.list([(ASTFactory.identifier2("u") as Expression)]), ASTFactory.block([])));
+  }
+  void test_visitForStatement_eu() {
+    assertSource("for (e;; u) {}", ASTFactory.forStatement(ASTFactory.identifier2("e"), null, ASTFactory.list([(ASTFactory.identifier2("u") as Expression)]), ASTFactory.block([])));
+  }
+  void test_visitForStatement_i() {
+    assertSource("for (var i;;) {}", ASTFactory.forStatement2(ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("i")]), null, null, ASTFactory.block([])));
+  }
+  void test_visitForStatement_ic() {
+    assertSource("for (var i; c;) {}", ASTFactory.forStatement2(ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("i")]), ASTFactory.identifier2("c"), null, ASTFactory.block([])));
+  }
+  void test_visitForStatement_icu() {
+    assertSource("for (var i; c; u) {}", ASTFactory.forStatement2(ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("i")]), ASTFactory.identifier2("c"), ASTFactory.list([(ASTFactory.identifier2("u") as Expression)]), ASTFactory.block([])));
+  }
+  void test_visitForStatement_iu() {
+    assertSource("for (var i;; u) {}", ASTFactory.forStatement2(ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("i")]), null, ASTFactory.list([(ASTFactory.identifier2("u") as Expression)]), ASTFactory.block([])));
+  }
+  void test_visitForStatement_u() {
+    assertSource("for (;; u) {}", ASTFactory.forStatement((null as Expression), null, ASTFactory.list([(ASTFactory.identifier2("u") as Expression)]), ASTFactory.block([])));
+  }
+  void test_visitFunctionDeclaration_getter() {
+    assertSource("get f() {}", ASTFactory.functionDeclaration(null, Keyword.GET, "f", ASTFactory.functionExpression()));
+  }
+  void test_visitFunctionDeclaration_normal() {
+    assertSource("f() {}", ASTFactory.functionDeclaration(null, null, "f", ASTFactory.functionExpression()));
+  }
+  void test_visitFunctionDeclaration_setter() {
+    assertSource("set f() {}", ASTFactory.functionDeclaration(null, Keyword.SET, "f", ASTFactory.functionExpression()));
+  }
+  void test_visitFunctionDeclarationStatement() {
+    assertSource("f() {};", ASTFactory.functionDeclarationStatement(null, null, "f", ASTFactory.functionExpression()));
+  }
+  void test_visitFunctionExpression() {
+    assertSource("() {}", ASTFactory.functionExpression());
+  }
+  void test_visitFunctionExpressionInvocation() {
+    assertSource("f()", ASTFactory.functionExpressionInvocation(ASTFactory.identifier2("f"), []));
+  }
+  void test_visitFunctionTypedFormalParameter_noType() {
+    assertSource("f()", ASTFactory.functionTypedFormalParameter(null, "f", []));
+  }
+  void test_visitFunctionTypedFormalParameter_type() {
+    assertSource("T f()", ASTFactory.functionTypedFormalParameter(ASTFactory.typeName3("T", []), "f", []));
+  }
+  void test_visitIfStatement_withElse() {
+    assertSource("if (c) {} else {}", ASTFactory.ifStatement2(ASTFactory.identifier2("c"), ASTFactory.block([]), ASTFactory.block([])));
+  }
+  void test_visitIfStatement_withoutElse() {
+    assertSource("if (c) {}", ASTFactory.ifStatement(ASTFactory.identifier2("c"), ASTFactory.block([])));
+  }
+  void test_visitImplementsClause_multiple() {
+    assertSource("implements A, B", ASTFactory.implementsClause([ASTFactory.typeName3("A", []), ASTFactory.typeName3("B", [])]));
+  }
+  void test_visitImplementsClause_single() {
+    assertSource("implements A", ASTFactory.implementsClause([ASTFactory.typeName3("A", [])]));
+  }
+  void test_visitImportDirective_combinator() {
+    assertSource("import 'a.dart' show A;", ASTFactory.importDirective2("a.dart", null, [ASTFactory.importShowCombinator([ASTFactory.identifier2("A")])]));
+  }
+  void test_visitImportDirective_combinators() {
+    assertSource("import 'a.dart' show A hide B;", ASTFactory.importDirective2("a.dart", null, [ASTFactory.importShowCombinator([ASTFactory.identifier2("A")]), ASTFactory.importHideCombinator([ASTFactory.identifier2("B")])]));
+  }
+  void test_visitImportDirective_minimal() {
+    assertSource("import 'a.dart';", ASTFactory.importDirective2("a.dart", null, []));
+  }
+  void test_visitImportDirective_prefix() {
+    assertSource("import 'a.dart' as p;", ASTFactory.importDirective2("a.dart", "p", []));
+  }
+  void test_visitImportDirective_prefix_combinator() {
+    assertSource("import 'a.dart' as p show A;", ASTFactory.importDirective2("a.dart", "p", [ASTFactory.importShowCombinator([ASTFactory.identifier2("A")])]));
+  }
+  void test_visitImportDirective_prefix_combinators() {
+    assertSource("import 'a.dart' as p show A hide B;", ASTFactory.importDirective2("a.dart", "p", [ASTFactory.importShowCombinator([ASTFactory.identifier2("A")]), ASTFactory.importHideCombinator([ASTFactory.identifier2("B")])]));
+  }
+  void test_visitImportHideCombinator_multiple() {
+    assertSource("hide a, b", ASTFactory.importHideCombinator([ASTFactory.identifier2("a"), ASTFactory.identifier2("b")]));
+  }
+  void test_visitImportHideCombinator_single() {
+    assertSource("hide a", ASTFactory.importHideCombinator([ASTFactory.identifier2("a")]));
+  }
+  void test_visitImportShowCombinator_multiple() {
+    assertSource("show a, b", ASTFactory.importShowCombinator([ASTFactory.identifier2("a"), ASTFactory.identifier2("b")]));
+  }
+  void test_visitImportShowCombinator_single() {
+    assertSource("show a", ASTFactory.importShowCombinator([ASTFactory.identifier2("a")]));
+  }
+  void test_visitIndexExpression() {
+    assertSource("a[i]", ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("i")));
+  }
+  void test_visitInstanceCreationExpression_named() {
+    assertSource("new C.c()", ASTFactory.instanceCreationExpression2(Keyword.NEW, ASTFactory.typeName3("C", []), "c", []));
+  }
+  void test_visitInstanceCreationExpression_unnamed() {
+    assertSource("new C()", ASTFactory.instanceCreationExpression(Keyword.NEW, ASTFactory.typeName3("C", []), []));
+  }
+  void test_visitIntegerLiteral() {
+    assertSource("42", ASTFactory.integer(42));
+  }
+  void test_visitInterpolationExpression_expression() {
+    assertSource("\${a}", ASTFactory.interpolationExpression(ASTFactory.identifier2("a")));
+  }
+  void test_visitInterpolationExpression_identifier() {
+    assertSource("\$a", ASTFactory.interpolationExpression2("a"));
+  }
+  void test_visitInterpolationString() {
+    assertSource("'x", ASTFactory.interpolationString("'x", "x"));
+  }
+  void test_visitIsExpression_negated() {
+    assertSource("a is! C", ASTFactory.isExpression(ASTFactory.identifier2("a"), true, ASTFactory.typeName3("C", [])));
+  }
+  void test_visitIsExpression_normal() {
+    assertSource("a is C", ASTFactory.isExpression(ASTFactory.identifier2("a"), false, ASTFactory.typeName3("C", [])));
+  }
+  void test_visitLabel() {
+    assertSource("a:", ASTFactory.label("a"));
+  }
+  void test_visitLabeledStatement_multiple() {
+    assertSource("a: b: return;", ASTFactory.labeledStatement(ASTFactory.list([ASTFactory.label("a"), ASTFactory.label("b")]), ASTFactory.returnStatement()));
+  }
+  void test_visitLabeledStatement_single() {
+    assertSource("a: return;", ASTFactory.labeledStatement(ASTFactory.list([ASTFactory.label("a")]), ASTFactory.returnStatement()));
+  }
+  void test_visitLibraryDirective() {
+    assertSource("library l;", ASTFactory.libraryDirective2("l"));
+  }
+  void test_visitLibraryIdentifier_multiple() {
+    assertSource("a.b.c", ASTFactory.libraryIdentifier([ASTFactory.identifier2("a"), ASTFactory.identifier2("b"), ASTFactory.identifier2("c")]));
+  }
+  void test_visitLibraryIdentifier_single() {
+    assertSource("a", ASTFactory.libraryIdentifier([ASTFactory.identifier2("a")]));
+  }
+  void test_visitListLiteral_const() {
+    assertSource("const []", ASTFactory.listLiteral2(Keyword.CONST, null, []));
+  }
+  void test_visitListLiteral_empty() {
+    assertSource("[]", ASTFactory.listLiteral([]));
+  }
+  void test_visitListLiteral_nonEmpty() {
+    assertSource("[a, b, c]", ASTFactory.listLiteral([ASTFactory.identifier2("a"), ASTFactory.identifier2("b"), ASTFactory.identifier2("c")]));
+  }
+  void test_visitMapLiteral_const() {
+    assertSource("const {}", ASTFactory.mapLiteral(Keyword.CONST, null, []));
+  }
+  void test_visitMapLiteral_empty() {
+    assertSource("{}", ASTFactory.mapLiteral2([]));
+  }
+  void test_visitMapLiteral_nonEmpty() {
+    assertSource("{'a' : a, 'b' : b, 'c' : c}", ASTFactory.mapLiteral2([ASTFactory.mapLiteralEntry("a", ASTFactory.identifier2("a")), ASTFactory.mapLiteralEntry("b", ASTFactory.identifier2("b")), ASTFactory.mapLiteralEntry("c", ASTFactory.identifier2("c"))]));
+  }
+  void test_visitMapLiteralEntry() {
+    assertSource("'a' : b", ASTFactory.mapLiteralEntry("a", ASTFactory.identifier2("b")));
+  }
+  void test_visitMethodDeclaration_external() {
+    assertSource("external m();", ASTFactory.methodDeclaration(null, null, null, null, ASTFactory.identifier2("m"), ASTFactory.formalParameterList([])));
+  }
+  void test_visitMethodDeclaration_external_returnType() {
+    assertSource("external T m();", ASTFactory.methodDeclaration(null, ASTFactory.typeName3("T", []), null, null, ASTFactory.identifier2("m"), ASTFactory.formalParameterList([])));
+  }
+  void test_visitMethodDeclaration_getter() {
+    assertSource("get m {}", ASTFactory.methodDeclaration2(null, null, Keyword.GET, null, ASTFactory.identifier2("m"), null, ASTFactory.blockFunctionBody([])));
+  }
+  void test_visitMethodDeclaration_getter_returnType() {
+    assertSource("T get m {}", ASTFactory.methodDeclaration2(null, ASTFactory.typeName3("T", []), Keyword.GET, null, ASTFactory.identifier2("m"), null, ASTFactory.blockFunctionBody([])));
+  }
+  void test_visitMethodDeclaration_getter_seturnType() {
+    assertSource("T set m(var v) {}", ASTFactory.methodDeclaration2(null, ASTFactory.typeName3("T", []), Keyword.SET, null, ASTFactory.identifier2("m"), ASTFactory.formalParameterList([ASTFactory.simpleFormalParameter(Keyword.VAR, "v")]), ASTFactory.blockFunctionBody([])));
+  }
+  void test_visitMethodDeclaration_minimal() {
+    assertSource("m() {}", ASTFactory.methodDeclaration2(null, null, null, null, ASTFactory.identifier2("m"), ASTFactory.formalParameterList([]), ASTFactory.blockFunctionBody([])));
+  }
+  void test_visitMethodDeclaration_multipleParameters() {
+    assertSource("m(var a, var b) {}", ASTFactory.methodDeclaration2(null, null, null, null, ASTFactory.identifier2("m"), ASTFactory.formalParameterList([ASTFactory.simpleFormalParameter(Keyword.VAR, "a"), ASTFactory.simpleFormalParameter(Keyword.VAR, "b")]), ASTFactory.blockFunctionBody([])));
+  }
+  void test_visitMethodDeclaration_operator() {
+    assertSource("operator +() {}", ASTFactory.methodDeclaration2(null, null, null, Keyword.OPERATOR, ASTFactory.identifier2("+"), ASTFactory.formalParameterList([]), ASTFactory.blockFunctionBody([])));
+  }
+  void test_visitMethodDeclaration_operator_returnType() {
+    assertSource("T operator +() {}", ASTFactory.methodDeclaration2(null, ASTFactory.typeName3("T", []), null, Keyword.OPERATOR, ASTFactory.identifier2("+"), ASTFactory.formalParameterList([]), ASTFactory.blockFunctionBody([])));
+  }
+  void test_visitMethodDeclaration_returnType() {
+    assertSource("T m() {}", ASTFactory.methodDeclaration2(null, ASTFactory.typeName3("T", []), null, null, ASTFactory.identifier2("m"), ASTFactory.formalParameterList([]), ASTFactory.blockFunctionBody([])));
+  }
+  void test_visitMethodDeclaration_setter() {
+    assertSource("set m(var v) {}", ASTFactory.methodDeclaration2(null, null, Keyword.SET, null, ASTFactory.identifier2("m"), ASTFactory.formalParameterList([ASTFactory.simpleFormalParameter(Keyword.VAR, "v")]), ASTFactory.blockFunctionBody([])));
+  }
+  void test_visitMethodDeclaration_static() {
+    assertSource("static m() {}", ASTFactory.methodDeclaration2(Keyword.STATIC, null, null, null, ASTFactory.identifier2("m"), ASTFactory.formalParameterList([]), ASTFactory.blockFunctionBody([])));
+  }
+  void test_visitMethodDeclaration_static_returnType() {
+    assertSource("static T m() {}", ASTFactory.methodDeclaration2(Keyword.STATIC, ASTFactory.typeName3("T", []), null, null, ASTFactory.identifier2("m"), ASTFactory.formalParameterList([]), ASTFactory.blockFunctionBody([])));
+  }
+  void test_visitMethodInvocation_noTarget() {
+    assertSource("m()", ASTFactory.methodInvocation2("m", []));
+  }
+  void test_visitMethodInvocation_target() {
+    assertSource("t.m()", ASTFactory.methodInvocation(ASTFactory.identifier2("t"), "m", []));
+  }
+  void test_visitNamedExpression() {
+    assertSource("a: b", ASTFactory.namedExpression("a", ASTFactory.identifier2("b")));
+  }
+  void test_visitNamedFormalParameter() {
+    assertSource("var a : 0", ASTFactory.namedFormalParameter(ASTFactory.simpleFormalParameter(Keyword.VAR, "a"), ASTFactory.integer(0)));
+  }
+  void test_visitNullLiteral() {
+    assertSource("null", ASTFactory.nullLiteral());
+  }
+  void test_visitParenthesizedExpression() {
+    assertSource("(a)", ASTFactory.parenthesizedExpression(ASTFactory.identifier2("a")));
+  }
+  void test_visitPartDirective() {
+    assertSource("part 'a.dart';", ASTFactory.partDirective2("a.dart"));
+  }
+  void test_visitPartOfDirective() {
+    assertSource("part of l;", ASTFactory.partOfDirective(ASTFactory.libraryIdentifier2(["l"])));
+  }
+  void test_visitPositionalFormalParameter() {
+    assertSource("var a = 0", ASTFactory.positionalFormalParameter(ASTFactory.simpleFormalParameter(Keyword.VAR, "a"), ASTFactory.integer(0)));
+  }
+  void test_visitPostfixExpression() {
+    assertSource("a++", ASTFactory.postfixExpression(ASTFactory.identifier2("a"), TokenType.PLUS_PLUS));
+  }
+  void test_visitPrefixedIdentifier() {
+    assertSource("a.b", ASTFactory.identifier4("a", "b"));
+  }
+  void test_visitPrefixExpression() {
+    assertSource("-a", ASTFactory.prefixExpression(TokenType.MINUS, ASTFactory.identifier2("a")));
+  }
+  void test_visitPropertyAccess() {
+    assertSource("a.b", ASTFactory.propertyAccess(ASTFactory.identifier2("a"), "b"));
+  }
+  void test_visitRedirectingConstructorInvocation_named() {
+    assertSource("this.c()", ASTFactory.redirectingConstructorInvocation2("c", []));
+  }
+  void test_visitRedirectingConstructorInvocation_unnamed() {
+    assertSource("this()", ASTFactory.redirectingConstructorInvocation([]));
+  }
+  void test_visitReturnStatement_expression() {
+    assertSource("return a;", ASTFactory.returnStatement2(ASTFactory.identifier2("a")));
+  }
+  void test_visitReturnStatement_noExpression() {
+    assertSource("return;", ASTFactory.returnStatement());
+  }
+  void test_visitScriptTag() {
+    String scriptTag = "!#/bin/dart.exe";
+    assertSource(scriptTag, ASTFactory.scriptTag(scriptTag));
+  }
+  void test_visitSimpleFormalParameter_keyword() {
+    assertSource("var a", ASTFactory.simpleFormalParameter(Keyword.VAR, "a"));
+  }
+  void test_visitSimpleFormalParameter_keyword_type() {
+    assertSource("final A a", ASTFactory.simpleFormalParameter2(Keyword.FINAL, ASTFactory.typeName3("A", []), "a"));
+  }
+  void test_visitSimpleFormalParameter_type() {
+    assertSource("A a", ASTFactory.simpleFormalParameter4(ASTFactory.typeName3("A", []), "a"));
+  }
+  void test_visitSimpleIdentifier() {
+    assertSource("a", ASTFactory.identifier2("a"));
+  }
+  void test_visitSimpleStringLiteral() {
+    assertSource("'a'", ASTFactory.string2("a"));
+  }
+  void test_visitStringInterpolation() {
+    assertSource("'a\${e}b'", ASTFactory.string([ASTFactory.interpolationString("'a", "a"), ASTFactory.interpolationExpression(ASTFactory.identifier2("e")), ASTFactory.interpolationString("b'", "b")]));
+  }
+  void test_visitSuperConstructorInvocation() {
+    assertSource("super()", ASTFactory.superConstructorInvocation([]));
+  }
+  void test_visitSuperConstructorInvocation_named() {
+    assertSource("super.c()", ASTFactory.superConstructorInvocation2("c", []));
+  }
+  void test_visitSuperExpression() {
+    assertSource("super", ASTFactory.superExpression());
+  }
+  void test_visitSwitchCase_multipleLabels() {
+    assertSource("l1: l2: case a: {}", ASTFactory.switchCase2(ASTFactory.list([ASTFactory.label("l1"), ASTFactory.label("l2")]), ASTFactory.identifier2("a"), [ASTFactory.block([])]));
+  }
+  void test_visitSwitchCase_multipleStatements() {
+    assertSource("case a: {} {}", ASTFactory.switchCase(ASTFactory.identifier2("a"), [ASTFactory.block([]), ASTFactory.block([])]));
+  }
+  void test_visitSwitchCase_noLabels() {
+    assertSource("case a: {}", ASTFactory.switchCase(ASTFactory.identifier2("a"), [ASTFactory.block([])]));
+  }
+  void test_visitSwitchCase_singleLabel() {
+    assertSource("l1: case a: {}", ASTFactory.switchCase2(ASTFactory.list([ASTFactory.label("l1")]), ASTFactory.identifier2("a"), [ASTFactory.block([])]));
+  }
+  void test_visitSwitchDefault_multipleLabels() {
+    assertSource("l1: l2: default: {}", ASTFactory.switchDefault(ASTFactory.list([ASTFactory.label("l1"), ASTFactory.label("l2")]), [ASTFactory.block([])]));
+  }
+  void test_visitSwitchDefault_multipleStatements() {
+    assertSource("default: {} {}", ASTFactory.switchDefault2([ASTFactory.block([]), ASTFactory.block([])]));
+  }
+  void test_visitSwitchDefault_noLabels() {
+    assertSource("default: {}", ASTFactory.switchDefault2([ASTFactory.block([])]));
+  }
+  void test_visitSwitchDefault_singleLabel() {
+    assertSource("l1: default: {}", ASTFactory.switchDefault(ASTFactory.list([ASTFactory.label("l1")]), [ASTFactory.block([])]));
+  }
+  void test_visitSwitchStatement() {
+    assertSource("switch (a) {case 'b': {} default: {}}", ASTFactory.switchStatement(ASTFactory.identifier2("a"), [ASTFactory.switchCase(ASTFactory.string2("b"), [ASTFactory.block([])]), ASTFactory.switchDefault2([ASTFactory.block([])])]));
+  }
+  void test_visitThisExpression() {
+    assertSource("this", ASTFactory.thisExpression());
+  }
+  void test_visitThrowStatement() {
+    assertSource("throw e", ASTFactory.throwExpression2(ASTFactory.identifier2("e")));
+  }
+  void test_visitTopLevelVariableDeclaration_multiple() {
+    assertSource("var a;", ASTFactory.topLevelVariableDeclaration2(Keyword.VAR, [ASTFactory.variableDeclaration("a")]));
+  }
+  void test_visitTopLevelVariableDeclaration_single() {
+    assertSource("var a, b;", ASTFactory.topLevelVariableDeclaration2(Keyword.VAR, [ASTFactory.variableDeclaration("a"), ASTFactory.variableDeclaration("b")]));
+  }
+  void test_visitTryStatement_catch() {
+    assertSource("try {} on E {}", ASTFactory.tryStatement2(ASTFactory.block([]), [ASTFactory.catchClause3(ASTFactory.typeName3("E", []), [])]));
+  }
+  void test_visitTryStatement_catches() {
+    assertSource("try {} on E {} on F {}", ASTFactory.tryStatement2(ASTFactory.block([]), [ASTFactory.catchClause3(ASTFactory.typeName3("E", []), []), ASTFactory.catchClause3(ASTFactory.typeName3("F", []), [])]));
+  }
+  void test_visitTryStatement_catchFinally() {
+    assertSource("try {} on E {} finally {}", ASTFactory.tryStatement3(ASTFactory.block([]), ASTFactory.list([ASTFactory.catchClause3(ASTFactory.typeName3("E", []), [])]), ASTFactory.block([])));
+  }
+  void test_visitTryStatement_finally() {
+    assertSource("try {} finally {}", ASTFactory.tryStatement(ASTFactory.block([]), ASTFactory.block([])));
+  }
+  void test_visitTypeAlias_generic() {
+    assertSource("typedef A F<B>();", ASTFactory.typeAlias(ASTFactory.typeName3("A", []), "F", ASTFactory.typeParameterList(["B"]), ASTFactory.formalParameterList([])));
+  }
+  void test_visitTypeAlias_nonGeneric() {
+    assertSource("typedef A F();", ASTFactory.typeAlias(ASTFactory.typeName3("A", []), "F", null, ASTFactory.formalParameterList([])));
+  }
+  void test_visitTypeArgumentList_multiple() {
+    assertSource("<E, F>", ASTFactory.typeArgumentList([ASTFactory.typeName3("E", []), ASTFactory.typeName3("F", [])]));
+  }
+  void test_visitTypeArgumentList_single() {
+    assertSource("<E>", ASTFactory.typeArgumentList([ASTFactory.typeName3("E", [])]));
+  }
+  void test_visitTypeName_multipleArgs() {
+    assertSource("C<D, E>", ASTFactory.typeName3("C", [ASTFactory.typeName3("D", []), ASTFactory.typeName3("E", [])]));
+  }
+  void test_visitTypeName_nestedArg() {
+    assertSource("C<D<E>>", ASTFactory.typeName3("C", [ASTFactory.typeName3("D", [ASTFactory.typeName3("E", [])])]));
+  }
+  void test_visitTypeName_noArgs() {
+    assertSource("C", ASTFactory.typeName3("C", []));
+  }
+  void test_visitTypeName_singleArg() {
+    assertSource("C<D>", ASTFactory.typeName3("C", [ASTFactory.typeName3("D", [])]));
+  }
+  void test_visitTypeParameter_withExtends() {
+    assertSource("E extends C", ASTFactory.typeParameter2("E", ASTFactory.typeName3("C", [])));
+  }
+  void test_visitTypeParameter_withoutExtends() {
+    assertSource("E", ASTFactory.typeParameter("E"));
+  }
+  void test_visitTypeParameterList_multiple() {
+    assertSource("<E, F>", ASTFactory.typeParameterList(["E", "F"]));
+  }
+  void test_visitTypeParameterList_single() {
+    assertSource("<E>", ASTFactory.typeParameterList(["E"]));
+  }
+  void test_visitVariableDeclaration_initialized() {
+    assertSource("a = b", ASTFactory.variableDeclaration2("a", ASTFactory.identifier2("b")));
+  }
+  void test_visitVariableDeclaration_uninitialized() {
+    assertSource("a", ASTFactory.variableDeclaration("a"));
+  }
+  void test_visitVariableDeclarationList_const_type() {
+    assertSource("const C a, b", ASTFactory.variableDeclarationList(Keyword.CONST, ASTFactory.typeName3("C", []), [ASTFactory.variableDeclaration("a"), ASTFactory.variableDeclaration("b")]));
+  }
+  void test_visitVariableDeclarationList_final_noType() {
+    assertSource("final a, b", ASTFactory.variableDeclarationList2(Keyword.FINAL, [ASTFactory.variableDeclaration("a"), ASTFactory.variableDeclaration("b")]));
+  }
+  void test_visitVariableDeclarationList_type() {
+    assertSource("C a, b", ASTFactory.variableDeclarationList(null, ASTFactory.typeName3("C", []), [ASTFactory.variableDeclaration("a"), ASTFactory.variableDeclaration("b")]));
+  }
+  void test_visitVariableDeclarationList_var() {
+    assertSource("var a, b", ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("a"), ASTFactory.variableDeclaration("b")]));
+  }
+  void test_visitVariableDeclarationStatement() {
+    assertSource("C c;", ASTFactory.variableDeclarationStatement(null, ASTFactory.typeName3("C", []), [ASTFactory.variableDeclaration("c")]));
+  }
+  void test_visitWhileStatement() {
+    assertSource("while (c) {}", ASTFactory.whileStatement(ASTFactory.identifier2("c"), ASTFactory.block([])));
+  }
+  void test_visitWithClause_multiple() {
+    assertSource("with A, B, C", ASTFactory.withClause([ASTFactory.typeName3("A", []), ASTFactory.typeName3("B", []), ASTFactory.typeName3("C", [])]));
+  }
+  void test_visitWithClause_single() {
+    assertSource("with A", ASTFactory.withClause([ASTFactory.typeName3("A", [])]));
+  }
+  /**
+   * Assert that a {@code ToSourceVisitor} will produce the expected source when visiting the given
+   * node.
+   * @param expectedSource the source string that the visitor is expected to produce
+   * @param node the AST node being visited to produce the actual source
+   * @throws AFE if the visitor does not produce the expected source for the given node
+   */
+  void assertSource(String expectedSource, ASTNode node) {
+    PrintStringWriter writer = new PrintStringWriter();
+    node.accept(new ToSourceVisitor(writer));
+    JUnitTestCase.assertEquals(expectedSource, writer.toString());
+  }
+  static dartSuite() {
+    _ut.group('ToSourceVisitorTest', () {
+      _ut.test('test_visitAdjacentStrings', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitAdjacentStrings);
+      });
+      _ut.test('test_visitAnnotation_constant', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitAnnotation_constant);
+      });
+      _ut.test('test_visitAnnotation_constructor', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitAnnotation_constructor);
+      });
+      _ut.test('test_visitArgumentDefinitionTest', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitArgumentDefinitionTest);
+      });
+      _ut.test('test_visitArgumentList', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitArgumentList);
+      });
+      _ut.test('test_visitAsExpression', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitAsExpression);
+      });
+      _ut.test('test_visitAssertStatement', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitAssertStatement);
+      });
+      _ut.test('test_visitAssignmentExpression', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitAssignmentExpression);
+      });
+      _ut.test('test_visitBinaryExpression', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitBinaryExpression);
+      });
+      _ut.test('test_visitBlockFunctionBody', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitBlockFunctionBody);
+      });
+      _ut.test('test_visitBlock_empty', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitBlock_empty);
+      });
+      _ut.test('test_visitBlock_nonEmpty', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitBlock_nonEmpty);
+      });
+      _ut.test('test_visitBooleanLiteral_false', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitBooleanLiteral_false);
+      });
+      _ut.test('test_visitBooleanLiteral_true', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitBooleanLiteral_true);
+      });
+      _ut.test('test_visitBreakStatement_label', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitBreakStatement_label);
+      });
+      _ut.test('test_visitBreakStatement_noLabel', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitBreakStatement_noLabel);
+      });
+      _ut.test('test_visitCascadeExpression_field', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitCascadeExpression_field);
+      });
+      _ut.test('test_visitCascadeExpression_index', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitCascadeExpression_index);
+      });
+      _ut.test('test_visitCascadeExpression_method', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitCascadeExpression_method);
+      });
+      _ut.test('test_visitCatchClause_catch_noStack', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitCatchClause_catch_noStack);
+      });
+      _ut.test('test_visitCatchClause_catch_stack', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitCatchClause_catch_stack);
+      });
+      _ut.test('test_visitCatchClause_on', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitCatchClause_on);
+      });
+      _ut.test('test_visitCatchClause_on_catch', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitCatchClause_on_catch);
+      });
+      _ut.test('test_visitClassDeclaration_abstract', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassDeclaration_abstract);
+      });
+      _ut.test('test_visitClassDeclaration_empty', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassDeclaration_empty);
+      });
+      _ut.test('test_visitClassDeclaration_extends', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassDeclaration_extends);
+      });
+      _ut.test('test_visitClassDeclaration_extends_implements', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassDeclaration_extends_implements);
+      });
+      _ut.test('test_visitClassDeclaration_extends_with', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassDeclaration_extends_with);
+      });
+      _ut.test('test_visitClassDeclaration_extends_with_implements', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassDeclaration_extends_with_implements);
+      });
+      _ut.test('test_visitClassDeclaration_implements', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassDeclaration_implements);
+      });
+      _ut.test('test_visitClassDeclaration_multipleMember', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassDeclaration_multipleMember);
+      });
+      _ut.test('test_visitClassDeclaration_parameters', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassDeclaration_parameters);
+      });
+      _ut.test('test_visitClassDeclaration_parameters_extends', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassDeclaration_parameters_extends);
+      });
+      _ut.test('test_visitClassDeclaration_parameters_extends_implements', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassDeclaration_parameters_extends_implements);
+      });
+      _ut.test('test_visitClassDeclaration_parameters_extends_with', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassDeclaration_parameters_extends_with);
+      });
+      _ut.test('test_visitClassDeclaration_parameters_extends_with_implements', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassDeclaration_parameters_extends_with_implements);
+      });
+      _ut.test('test_visitClassDeclaration_parameters_implements', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassDeclaration_parameters_implements);
+      });
+      _ut.test('test_visitClassDeclaration_singleMember', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassDeclaration_singleMember);
+      });
+      _ut.test('test_visitClassTypeAlias_abstract', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassTypeAlias_abstract);
+      });
+      _ut.test('test_visitClassTypeAlias_abstract_implements', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassTypeAlias_abstract_implements);
+      });
+      _ut.test('test_visitClassTypeAlias_generic', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassTypeAlias_generic);
+      });
+      _ut.test('test_visitClassTypeAlias_implements', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassTypeAlias_implements);
+      });
+      _ut.test('test_visitClassTypeAlias_minimal', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassTypeAlias_minimal);
+      });
+      _ut.test('test_visitClassTypeAlias_parameters_abstract', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassTypeAlias_parameters_abstract);
+      });
+      _ut.test('test_visitClassTypeAlias_parameters_abstract_implements', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassTypeAlias_parameters_abstract_implements);
+      });
+      _ut.test('test_visitClassTypeAlias_parameters_implements', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitClassTypeAlias_parameters_implements);
+      });
+      _ut.test('test_visitComment', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitComment);
+      });
+      _ut.test('test_visitCommentReference', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitCommentReference);
+      });
+      _ut.test('test_visitCompilationUnit_declaration', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitCompilationUnit_declaration);
+      });
+      _ut.test('test_visitCompilationUnit_directive', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitCompilationUnit_directive);
+      });
+      _ut.test('test_visitCompilationUnit_directive_declaration', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitCompilationUnit_directive_declaration);
+      });
+      _ut.test('test_visitCompilationUnit_empty', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitCompilationUnit_empty);
+      });
+      _ut.test('test_visitCompilationUnit_script', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitCompilationUnit_script);
+      });
+      _ut.test('test_visitCompilationUnit_script_declaration', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitCompilationUnit_script_declaration);
+      });
+      _ut.test('test_visitCompilationUnit_script_directive', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitCompilationUnit_script_directive);
+      });
+      _ut.test('test_visitCompilationUnit_script_directives_declarations', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitCompilationUnit_script_directives_declarations);
+      });
+      _ut.test('test_visitConditionalExpression', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitConditionalExpression);
+      });
+      _ut.test('test_visitConstructorDeclaration_const', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitConstructorDeclaration_const);
+      });
+      _ut.test('test_visitConstructorDeclaration_external', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitConstructorDeclaration_external);
+      });
+      _ut.test('test_visitConstructorDeclaration_minimal', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitConstructorDeclaration_minimal);
+      });
+      _ut.test('test_visitConstructorDeclaration_multipleInitializers', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitConstructorDeclaration_multipleInitializers);
+      });
+      _ut.test('test_visitConstructorDeclaration_multipleParameters', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitConstructorDeclaration_multipleParameters);
+      });
+      _ut.test('test_visitConstructorDeclaration_named', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitConstructorDeclaration_named);
+      });
+      _ut.test('test_visitConstructorDeclaration_singleInitializer', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitConstructorDeclaration_singleInitializer);
+      });
+      _ut.test('test_visitConstructorFieldInitializer_withThis', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitConstructorFieldInitializer_withThis);
+      });
+      _ut.test('test_visitConstructorFieldInitializer_withoutThis', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitConstructorFieldInitializer_withoutThis);
+      });
+      _ut.test('test_visitConstructorName_named_prefix', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitConstructorName_named_prefix);
+      });
+      _ut.test('test_visitConstructorName_unnamed_noPrefix', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitConstructorName_unnamed_noPrefix);
+      });
+      _ut.test('test_visitConstructorName_unnamed_prefix', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitConstructorName_unnamed_prefix);
+      });
+      _ut.test('test_visitContinueStatement_label', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitContinueStatement_label);
+      });
+      _ut.test('test_visitContinueStatement_noLabel', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitContinueStatement_noLabel);
+      });
+      _ut.test('test_visitDefaultFormalParameter_named_noValue', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitDefaultFormalParameter_named_noValue);
+      });
+      _ut.test('test_visitDefaultFormalParameter_named_value', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitDefaultFormalParameter_named_value);
+      });
+      _ut.test('test_visitDefaultFormalParameter_positional_noValue', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitDefaultFormalParameter_positional_noValue);
+      });
+      _ut.test('test_visitDefaultFormalParameter_positional_value', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitDefaultFormalParameter_positional_value);
+      });
+      _ut.test('test_visitDoStatement', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitDoStatement);
+      });
+      _ut.test('test_visitDoubleLiteral', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitDoubleLiteral);
+      });
+      _ut.test('test_visitEmptyFunctionBody', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitEmptyFunctionBody);
+      });
+      _ut.test('test_visitEmptyStatement', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitEmptyStatement);
+      });
+      _ut.test('test_visitExportDirective_combinator', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitExportDirective_combinator);
+      });
+      _ut.test('test_visitExportDirective_combinators', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitExportDirective_combinators);
+      });
+      _ut.test('test_visitExportDirective_minimal', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitExportDirective_minimal);
+      });
+      _ut.test('test_visitExpressionFunctionBody', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitExpressionFunctionBody);
+      });
+      _ut.test('test_visitExpressionStatement', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitExpressionStatement);
+      });
+      _ut.test('test_visitExtendsClause', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitExtendsClause);
+      });
+      _ut.test('test_visitFieldDeclaration_instance', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFieldDeclaration_instance);
+      });
+      _ut.test('test_visitFieldDeclaration_static', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFieldDeclaration_static);
+      });
+      _ut.test('test_visitFieldFormalParameter_keyword', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFieldFormalParameter_keyword);
+      });
+      _ut.test('test_visitFieldFormalParameter_keywordAndType', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFieldFormalParameter_keywordAndType);
+      });
+      _ut.test('test_visitFieldFormalParameter_type', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFieldFormalParameter_type);
+      });
+      _ut.test('test_visitForEachStatement', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitForEachStatement);
+      });
+      _ut.test('test_visitForStatement_c', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitForStatement_c);
+      });
+      _ut.test('test_visitForStatement_cu', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitForStatement_cu);
+      });
+      _ut.test('test_visitForStatement_e', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitForStatement_e);
+      });
+      _ut.test('test_visitForStatement_ec', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitForStatement_ec);
+      });
+      _ut.test('test_visitForStatement_ecu', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitForStatement_ecu);
+      });
+      _ut.test('test_visitForStatement_eu', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitForStatement_eu);
+      });
+      _ut.test('test_visitForStatement_i', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitForStatement_i);
+      });
+      _ut.test('test_visitForStatement_ic', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitForStatement_ic);
+      });
+      _ut.test('test_visitForStatement_icu', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitForStatement_icu);
+      });
+      _ut.test('test_visitForStatement_iu', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitForStatement_iu);
+      });
+      _ut.test('test_visitForStatement_u', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitForStatement_u);
+      });
+      _ut.test('test_visitFormalParameterList_empty', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFormalParameterList_empty);
+      });
+      _ut.test('test_visitFormalParameterList_n', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFormalParameterList_n);
+      });
+      _ut.test('test_visitFormalParameterList_nn', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFormalParameterList_nn);
+      });
+      _ut.test('test_visitFormalParameterList_p', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFormalParameterList_p);
+      });
+      _ut.test('test_visitFormalParameterList_pp', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFormalParameterList_pp);
+      });
+      _ut.test('test_visitFormalParameterList_r', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFormalParameterList_r);
+      });
+      _ut.test('test_visitFormalParameterList_rn', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFormalParameterList_rn);
+      });
+      _ut.test('test_visitFormalParameterList_rnn', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFormalParameterList_rnn);
+      });
+      _ut.test('test_visitFormalParameterList_rp', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFormalParameterList_rp);
+      });
+      _ut.test('test_visitFormalParameterList_rpp', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFormalParameterList_rpp);
+      });
+      _ut.test('test_visitFormalParameterList_rr', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFormalParameterList_rr);
+      });
+      _ut.test('test_visitFormalParameterList_rrn', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFormalParameterList_rrn);
+      });
+      _ut.test('test_visitFormalParameterList_rrnn', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFormalParameterList_rrnn);
+      });
+      _ut.test('test_visitFormalParameterList_rrp', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFormalParameterList_rrp);
+      });
+      _ut.test('test_visitFormalParameterList_rrpp', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFormalParameterList_rrpp);
+      });
+      _ut.test('test_visitFunctionDeclarationStatement', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFunctionDeclarationStatement);
+      });
+      _ut.test('test_visitFunctionDeclaration_getter', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFunctionDeclaration_getter);
+      });
+      _ut.test('test_visitFunctionDeclaration_normal', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFunctionDeclaration_normal);
+      });
+      _ut.test('test_visitFunctionDeclaration_setter', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFunctionDeclaration_setter);
+      });
+      _ut.test('test_visitFunctionExpression', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFunctionExpression);
+      });
+      _ut.test('test_visitFunctionExpressionInvocation', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFunctionExpressionInvocation);
+      });
+      _ut.test('test_visitFunctionTypedFormalParameter_noType', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFunctionTypedFormalParameter_noType);
+      });
+      _ut.test('test_visitFunctionTypedFormalParameter_type', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitFunctionTypedFormalParameter_type);
+      });
+      _ut.test('test_visitIfStatement_withElse', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitIfStatement_withElse);
+      });
+      _ut.test('test_visitIfStatement_withoutElse', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitIfStatement_withoutElse);
+      });
+      _ut.test('test_visitImplementsClause_multiple', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitImplementsClause_multiple);
+      });
+      _ut.test('test_visitImplementsClause_single', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitImplementsClause_single);
+      });
+      _ut.test('test_visitImportDirective_combinator', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitImportDirective_combinator);
+      });
+      _ut.test('test_visitImportDirective_combinators', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitImportDirective_combinators);
+      });
+      _ut.test('test_visitImportDirective_minimal', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitImportDirective_minimal);
+      });
+      _ut.test('test_visitImportDirective_prefix', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitImportDirective_prefix);
+      });
+      _ut.test('test_visitImportDirective_prefix_combinator', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitImportDirective_prefix_combinator);
+      });
+      _ut.test('test_visitImportDirective_prefix_combinators', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitImportDirective_prefix_combinators);
+      });
+      _ut.test('test_visitImportHideCombinator_multiple', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitImportHideCombinator_multiple);
+      });
+      _ut.test('test_visitImportHideCombinator_single', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitImportHideCombinator_single);
+      });
+      _ut.test('test_visitImportShowCombinator_multiple', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitImportShowCombinator_multiple);
+      });
+      _ut.test('test_visitImportShowCombinator_single', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitImportShowCombinator_single);
+      });
+      _ut.test('test_visitIndexExpression', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitIndexExpression);
+      });
+      _ut.test('test_visitInstanceCreationExpression_named', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitInstanceCreationExpression_named);
+      });
+      _ut.test('test_visitInstanceCreationExpression_unnamed', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitInstanceCreationExpression_unnamed);
+      });
+      _ut.test('test_visitIntegerLiteral', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitIntegerLiteral);
+      });
+      _ut.test('test_visitInterpolationExpression_expression', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitInterpolationExpression_expression);
+      });
+      _ut.test('test_visitInterpolationExpression_identifier', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitInterpolationExpression_identifier);
+      });
+      _ut.test('test_visitInterpolationString', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitInterpolationString);
+      });
+      _ut.test('test_visitIsExpression_negated', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitIsExpression_negated);
+      });
+      _ut.test('test_visitIsExpression_normal', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitIsExpression_normal);
+      });
+      _ut.test('test_visitLabel', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitLabel);
+      });
+      _ut.test('test_visitLabeledStatement_multiple', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitLabeledStatement_multiple);
+      });
+      _ut.test('test_visitLabeledStatement_single', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitLabeledStatement_single);
+      });
+      _ut.test('test_visitLibraryDirective', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitLibraryDirective);
+      });
+      _ut.test('test_visitLibraryIdentifier_multiple', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitLibraryIdentifier_multiple);
+      });
+      _ut.test('test_visitLibraryIdentifier_single', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitLibraryIdentifier_single);
+      });
+      _ut.test('test_visitListLiteral_const', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitListLiteral_const);
+      });
+      _ut.test('test_visitListLiteral_empty', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitListLiteral_empty);
+      });
+      _ut.test('test_visitListLiteral_nonEmpty', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitListLiteral_nonEmpty);
+      });
+      _ut.test('test_visitMapLiteralEntry', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitMapLiteralEntry);
+      });
+      _ut.test('test_visitMapLiteral_const', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitMapLiteral_const);
+      });
+      _ut.test('test_visitMapLiteral_empty', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitMapLiteral_empty);
+      });
+      _ut.test('test_visitMapLiteral_nonEmpty', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitMapLiteral_nonEmpty);
+      });
+      _ut.test('test_visitMethodDeclaration_external', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitMethodDeclaration_external);
+      });
+      _ut.test('test_visitMethodDeclaration_external_returnType', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitMethodDeclaration_external_returnType);
+      });
+      _ut.test('test_visitMethodDeclaration_getter', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitMethodDeclaration_getter);
+      });
+      _ut.test('test_visitMethodDeclaration_getter_returnType', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitMethodDeclaration_getter_returnType);
+      });
+      _ut.test('test_visitMethodDeclaration_getter_seturnType', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitMethodDeclaration_getter_seturnType);
+      });
+      _ut.test('test_visitMethodDeclaration_minimal', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitMethodDeclaration_minimal);
+      });
+      _ut.test('test_visitMethodDeclaration_multipleParameters', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitMethodDeclaration_multipleParameters);
+      });
+      _ut.test('test_visitMethodDeclaration_operator', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitMethodDeclaration_operator);
+      });
+      _ut.test('test_visitMethodDeclaration_operator_returnType', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitMethodDeclaration_operator_returnType);
+      });
+      _ut.test('test_visitMethodDeclaration_returnType', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitMethodDeclaration_returnType);
+      });
+      _ut.test('test_visitMethodDeclaration_setter', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitMethodDeclaration_setter);
+      });
+      _ut.test('test_visitMethodDeclaration_static', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitMethodDeclaration_static);
+      });
+      _ut.test('test_visitMethodDeclaration_static_returnType', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitMethodDeclaration_static_returnType);
+      });
+      _ut.test('test_visitMethodInvocation_noTarget', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitMethodInvocation_noTarget);
+      });
+      _ut.test('test_visitMethodInvocation_target', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitMethodInvocation_target);
+      });
+      _ut.test('test_visitNamedExpression', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitNamedExpression);
+      });
+      _ut.test('test_visitNamedFormalParameter', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitNamedFormalParameter);
+      });
+      _ut.test('test_visitNullLiteral', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitNullLiteral);
+      });
+      _ut.test('test_visitParenthesizedExpression', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitParenthesizedExpression);
+      });
+      _ut.test('test_visitPartDirective', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitPartDirective);
+      });
+      _ut.test('test_visitPartOfDirective', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitPartOfDirective);
+      });
+      _ut.test('test_visitPositionalFormalParameter', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitPositionalFormalParameter);
+      });
+      _ut.test('test_visitPostfixExpression', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitPostfixExpression);
+      });
+      _ut.test('test_visitPrefixExpression', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitPrefixExpression);
+      });
+      _ut.test('test_visitPrefixedIdentifier', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitPrefixedIdentifier);
+      });
+      _ut.test('test_visitPropertyAccess', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitPropertyAccess);
+      });
+      _ut.test('test_visitRedirectingConstructorInvocation_named', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitRedirectingConstructorInvocation_named);
+      });
+      _ut.test('test_visitRedirectingConstructorInvocation_unnamed', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitRedirectingConstructorInvocation_unnamed);
+      });
+      _ut.test('test_visitReturnStatement_expression', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitReturnStatement_expression);
+      });
+      _ut.test('test_visitReturnStatement_noExpression', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitReturnStatement_noExpression);
+      });
+      _ut.test('test_visitScriptTag', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitScriptTag);
+      });
+      _ut.test('test_visitSimpleFormalParameter_keyword', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitSimpleFormalParameter_keyword);
+      });
+      _ut.test('test_visitSimpleFormalParameter_keyword_type', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitSimpleFormalParameter_keyword_type);
+      });
+      _ut.test('test_visitSimpleFormalParameter_type', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitSimpleFormalParameter_type);
+      });
+      _ut.test('test_visitSimpleIdentifier', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitSimpleIdentifier);
+      });
+      _ut.test('test_visitSimpleStringLiteral', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitSimpleStringLiteral);
+      });
+      _ut.test('test_visitStringInterpolation', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitStringInterpolation);
+      });
+      _ut.test('test_visitSuperConstructorInvocation', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitSuperConstructorInvocation);
+      });
+      _ut.test('test_visitSuperConstructorInvocation_named', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitSuperConstructorInvocation_named);
+      });
+      _ut.test('test_visitSuperExpression', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitSuperExpression);
+      });
+      _ut.test('test_visitSwitchCase_multipleLabels', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitSwitchCase_multipleLabels);
+      });
+      _ut.test('test_visitSwitchCase_multipleStatements', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitSwitchCase_multipleStatements);
+      });
+      _ut.test('test_visitSwitchCase_noLabels', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitSwitchCase_noLabels);
+      });
+      _ut.test('test_visitSwitchCase_singleLabel', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitSwitchCase_singleLabel);
+      });
+      _ut.test('test_visitSwitchDefault_multipleLabels', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitSwitchDefault_multipleLabels);
+      });
+      _ut.test('test_visitSwitchDefault_multipleStatements', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitSwitchDefault_multipleStatements);
+      });
+      _ut.test('test_visitSwitchDefault_noLabels', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitSwitchDefault_noLabels);
+      });
+      _ut.test('test_visitSwitchDefault_singleLabel', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitSwitchDefault_singleLabel);
+      });
+      _ut.test('test_visitSwitchStatement', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitSwitchStatement);
+      });
+      _ut.test('test_visitThisExpression', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitThisExpression);
+      });
+      _ut.test('test_visitThrowStatement', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitThrowStatement);
+      });
+      _ut.test('test_visitTopLevelVariableDeclaration_multiple', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitTopLevelVariableDeclaration_multiple);
+      });
+      _ut.test('test_visitTopLevelVariableDeclaration_single', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitTopLevelVariableDeclaration_single);
+      });
+      _ut.test('test_visitTryStatement_catch', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitTryStatement_catch);
+      });
+      _ut.test('test_visitTryStatement_catchFinally', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitTryStatement_catchFinally);
+      });
+      _ut.test('test_visitTryStatement_catches', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitTryStatement_catches);
+      });
+      _ut.test('test_visitTryStatement_finally', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitTryStatement_finally);
+      });
+      _ut.test('test_visitTypeAlias_generic', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitTypeAlias_generic);
+      });
+      _ut.test('test_visitTypeAlias_nonGeneric', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitTypeAlias_nonGeneric);
+      });
+      _ut.test('test_visitTypeArgumentList_multiple', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitTypeArgumentList_multiple);
+      });
+      _ut.test('test_visitTypeArgumentList_single', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitTypeArgumentList_single);
+      });
+      _ut.test('test_visitTypeName_multipleArgs', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitTypeName_multipleArgs);
+      });
+      _ut.test('test_visitTypeName_nestedArg', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitTypeName_nestedArg);
+      });
+      _ut.test('test_visitTypeName_noArgs', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitTypeName_noArgs);
+      });
+      _ut.test('test_visitTypeName_singleArg', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitTypeName_singleArg);
+      });
+      _ut.test('test_visitTypeParameterList_multiple', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitTypeParameterList_multiple);
+      });
+      _ut.test('test_visitTypeParameterList_single', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitTypeParameterList_single);
+      });
+      _ut.test('test_visitTypeParameter_withExtends', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitTypeParameter_withExtends);
+      });
+      _ut.test('test_visitTypeParameter_withoutExtends', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitTypeParameter_withoutExtends);
+      });
+      _ut.test('test_visitVariableDeclarationList_const_type', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitVariableDeclarationList_const_type);
+      });
+      _ut.test('test_visitVariableDeclarationList_final_noType', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitVariableDeclarationList_final_noType);
+      });
+      _ut.test('test_visitVariableDeclarationList_type', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitVariableDeclarationList_type);
+      });
+      _ut.test('test_visitVariableDeclarationList_var', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitVariableDeclarationList_var);
+      });
+      _ut.test('test_visitVariableDeclarationStatement', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitVariableDeclarationStatement);
+      });
+      _ut.test('test_visitVariableDeclaration_initialized', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitVariableDeclaration_initialized);
+      });
+      _ut.test('test_visitVariableDeclaration_uninitialized', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitVariableDeclaration_uninitialized);
+      });
+      _ut.test('test_visitWhileStatement', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitWhileStatement);
+      });
+      _ut.test('test_visitWithClause_multiple', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitWithClause_multiple);
+      });
+      _ut.test('test_visitWithClause_single', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitWithClause_single);
+      });
+    });
+  }
+}
+class IndexExpressionTest extends EngineTestCase {
+  void test_inGetterContext_assignment_compound_left() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.assignmentExpression(expression, TokenType.PLUS_EQ, null);
+    JUnitTestCase.assertTrue(expression.inGetterContext());
+  }
+  void test_inGetterContext_assignment_simple_left() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.assignmentExpression(expression, TokenType.EQ, null);
+    JUnitTestCase.assertFalse(expression.inGetterContext());
+  }
+  void test_inGetterContext_nonAssignment() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.binaryExpression(expression, TokenType.PLUS, null);
+    JUnitTestCase.assertTrue(expression.inGetterContext());
+  }
+  void test_inSetterContext_assignment_compound_left() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.assignmentExpression(expression, TokenType.PLUS_EQ, null);
+    JUnitTestCase.assertTrue(expression.inSetterContext());
+  }
+  void test_inSetterContext_assignment_compound_right() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.assignmentExpression(null, TokenType.PLUS_EQ, expression);
+    JUnitTestCase.assertFalse(expression.inSetterContext());
+  }
+  void test_inSetterContext_assignment_simple_left() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.assignmentExpression(expression, TokenType.EQ, null);
+    JUnitTestCase.assertTrue(expression.inSetterContext());
+  }
+  void test_inSetterContext_assignment_simple_right() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.assignmentExpression(null, TokenType.EQ, expression);
+    JUnitTestCase.assertFalse(expression.inSetterContext());
+  }
+  void test_inSetterContext_nonAssignment() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.binaryExpression(expression, TokenType.PLUS, null);
+    JUnitTestCase.assertFalse(expression.inSetterContext());
+  }
+  void test_inSetterContext_postfix() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.postfixExpression(expression, TokenType.PLUS_PLUS);
+    JUnitTestCase.assertTrue(expression.inSetterContext());
+  }
+  void test_inSetterContext_prefix_bang() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.prefixExpression(TokenType.BANG, expression);
+    JUnitTestCase.assertFalse(expression.inSetterContext());
+  }
+  void test_inSetterContext_prefix_minusMinus() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.prefixExpression(TokenType.MINUS_MINUS, expression);
+    JUnitTestCase.assertTrue(expression.inSetterContext());
+  }
+  void test_inSetterContext_prefix_plusPlus() {
+    IndexExpression expression = ASTFactory.indexExpression(ASTFactory.identifier2("a"), ASTFactory.identifier2("b"));
+    ASTFactory.prefixExpression(TokenType.PLUS_PLUS, expression);
+    JUnitTestCase.assertTrue(expression.inSetterContext());
+  }
+  static dartSuite() {
+    _ut.group('IndexExpressionTest', () {
+      _ut.test('test_inGetterContext_assignment_compound_left', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inGetterContext_assignment_compound_left);
+      });
+      _ut.test('test_inGetterContext_assignment_simple_left', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inGetterContext_assignment_simple_left);
+      });
+      _ut.test('test_inGetterContext_nonAssignment', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inGetterContext_nonAssignment);
+      });
+      _ut.test('test_inSetterContext_assignment_compound_left', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inSetterContext_assignment_compound_left);
+      });
+      _ut.test('test_inSetterContext_assignment_compound_right', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inSetterContext_assignment_compound_right);
+      });
+      _ut.test('test_inSetterContext_assignment_simple_left', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inSetterContext_assignment_simple_left);
+      });
+      _ut.test('test_inSetterContext_assignment_simple_right', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inSetterContext_assignment_simple_right);
+      });
+      _ut.test('test_inSetterContext_nonAssignment', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inSetterContext_nonAssignment);
+      });
+      _ut.test('test_inSetterContext_postfix', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inSetterContext_postfix);
+      });
+      _ut.test('test_inSetterContext_prefix_bang', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inSetterContext_prefix_bang);
+      });
+      _ut.test('test_inSetterContext_prefix_minusMinus', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inSetterContext_prefix_minusMinus);
+      });
+      _ut.test('test_inSetterContext_prefix_plusPlus', () {
+        final __test = new IndexExpressionTest();
+        runJUnitTest(__test, __test.test_inSetterContext_prefix_plusPlus);
+      });
+    });
+  }
+}
+class ConstantEvaluatorTest extends ParserTestCase {
+  void fail_constructor() {
+    Object value = getConstantValue("?");
+    JUnitTestCase.assertEquals(null, value);
+  }
+  void fail_identifier_class() {
+    Object value = getConstantValue("?");
+    JUnitTestCase.assertEquals(null, value);
+  }
+  void fail_identifier_function() {
+    Object value = getConstantValue("?");
+    JUnitTestCase.assertEquals(null, value);
+  }
+  void fail_identifier_static() {
+    Object value = getConstantValue("?");
+    JUnitTestCase.assertEquals(null, value);
+  }
+  void fail_identifier_staticMethod() {
+    Object value = getConstantValue("?");
+    JUnitTestCase.assertEquals(null, value);
+  }
+  void fail_identifier_topLevel() {
+    Object value = getConstantValue("?");
+    JUnitTestCase.assertEquals(null, value);
+  }
+  void fail_identifier_typeVariable() {
+    Object value = getConstantValue("?");
+    JUnitTestCase.assertEquals(null, value);
+  }
+  void test_binary_bitAnd() {
+    Object value = getConstantValue("74 & 42");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(74 & 42, ((value as int)));
+  }
+  void test_binary_bitOr() {
+    Object value = getConstantValue("74 | 42");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(74 | 42, ((value as int)));
+  }
+  void test_binary_bitXor() {
+    Object value = getConstantValue("74 ^ 42");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(74 ^ 42, ((value as int)));
+  }
+  void test_binary_divide_double() {
+    Object value = getConstantValue("3.2 / 2.3");
+    EngineTestCase.assertInstanceOf(double, value);
+    JUnitTestCase.assertEquals(3.2 / 2.3, ((value as double)));
+  }
+  void test_binary_divide_integer() {
+    Object value = getConstantValue("3 / 2");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(1, ((value as int)));
+  }
+  void test_binary_equal_boolean() {
+    Object value = getConstantValue("true == false");
+    JUnitTestCase.assertEquals(false, value);
+  }
+  void test_binary_equal_integer() {
+    Object value = getConstantValue("2 == 3");
+    JUnitTestCase.assertEquals(false, value);
+  }
+  void test_binary_equal_invalidLeft() {
+    Object value = getConstantValue("a == 3");
+    JUnitTestCase.assertEquals(ConstantEvaluator.NOT_A_CONSTANT, value);
+  }
+  void test_binary_equal_invalidRight() {
+    Object value = getConstantValue("2 == a");
+    JUnitTestCase.assertEquals(ConstantEvaluator.NOT_A_CONSTANT, value);
+  }
+  void test_binary_equal_string() {
+    Object value = getConstantValue("'a' == 'b'");
+    JUnitTestCase.assertEquals(false, value);
+  }
+  void test_binary_greaterThan() {
+    Object value = getConstantValue("2 > 3");
+    JUnitTestCase.assertEquals(false, value);
+  }
+  void test_binary_greaterThanOrEqual() {
+    Object value = getConstantValue("2 >= 3");
+    JUnitTestCase.assertEquals(false, value);
+  }
+  void test_binary_leftShift() {
+    Object value = getConstantValue("16 << 2");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(64, ((value as int)));
+  }
+  void test_binary_lessThan() {
+    Object value = getConstantValue("2 < 3");
+    JUnitTestCase.assertEquals(true, value);
+  }
+  void test_binary_lessThanOrEqual() {
+    Object value = getConstantValue("2 <= 3");
+    JUnitTestCase.assertEquals(true, value);
+  }
+  void test_binary_logicalAnd() {
+    Object value = getConstantValue("true && false");
+    JUnitTestCase.assertEquals(false, value);
+  }
+  void test_binary_logicalOr() {
+    Object value = getConstantValue("true || false");
+    JUnitTestCase.assertEquals(true, value);
+  }
+  void test_binary_minus_double() {
+    Object value = getConstantValue("3.2 - 2.3");
+    EngineTestCase.assertInstanceOf(double, value);
+    JUnitTestCase.assertEquals(3.2 - 2.3, ((value as double)));
+  }
+  void test_binary_minus_integer() {
+    Object value = getConstantValue("3 - 2");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(1, ((value as int)));
+  }
+  void test_binary_notEqual_boolean() {
+    Object value = getConstantValue("true != false");
+    JUnitTestCase.assertEquals(true, value);
+  }
+  void test_binary_notEqual_integer() {
+    Object value = getConstantValue("2 != 3");
+    JUnitTestCase.assertEquals(true, value);
+  }
+  void test_binary_notEqual_invalidLeft() {
+    Object value = getConstantValue("a != 3");
+    JUnitTestCase.assertEquals(ConstantEvaluator.NOT_A_CONSTANT, value);
+  }
+  void test_binary_notEqual_invalidRight() {
+    Object value = getConstantValue("2 != a");
+    JUnitTestCase.assertEquals(ConstantEvaluator.NOT_A_CONSTANT, value);
+  }
+  void test_binary_notEqual_string() {
+    Object value = getConstantValue("'a' != 'b'");
+    JUnitTestCase.assertEquals(true, value);
+  }
+  void test_binary_plus_double() {
+    Object value = getConstantValue("2.3 + 3.2");
+    EngineTestCase.assertInstanceOf(double, value);
+    JUnitTestCase.assertEquals(2.3 + 3.2, ((value as double)));
+  }
+  void test_binary_plus_integer() {
+    Object value = getConstantValue("2 + 3");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(5, ((value as int)));
+  }
+  void test_binary_remainder_double() {
+    Object value = getConstantValue("3.2 % 2.3");
+    EngineTestCase.assertInstanceOf(double, value);
+    JUnitTestCase.assertEquals(3.2 % 2.3, ((value as double)));
+  }
+  void test_binary_remainder_integer() {
+    Object value = getConstantValue("8 % 3");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(2, ((value as int)));
+  }
+  void test_binary_rightShift() {
+    Object value = getConstantValue("64 >> 2");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(16, ((value as int)));
+  }
+  void test_binary_times_double() {
+    Object value = getConstantValue("2.3 * 3.2");
+    EngineTestCase.assertInstanceOf(double, value);
+    JUnitTestCase.assertEquals(2.3 * 3.2, ((value as double)));
+  }
+  void test_binary_times_integer() {
+    Object value = getConstantValue("2 * 3");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(6, ((value as int)));
+  }
+  void test_binary_truncatingDivide_double() {
+    Object value = getConstantValue("3.2 ~/ 2.3");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(1, ((value as int)));
+  }
+  void test_binary_truncatingDivide_integer() {
+    Object value = getConstantValue("10 ~/ 3");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(3, ((value as int)));
+  }
+  void test_literal_boolean_false() {
+    Object value = getConstantValue("false");
+    JUnitTestCase.assertEquals(false, value);
+  }
+  void test_literal_boolean_true() {
+    Object value = getConstantValue("true");
+    JUnitTestCase.assertEquals(true, value);
+  }
+  void test_literal_list() {
+    Object value = getConstantValue("['a', 'b', 'c']");
+    EngineTestCase.assertInstanceOf(List, value);
+    List<Object> list = (value as List<Object>);
+    JUnitTestCase.assertEquals(3, list.length);
+    JUnitTestCase.assertEquals("a", list[0]);
+    JUnitTestCase.assertEquals("b", list[1]);
+    JUnitTestCase.assertEquals("c", list[2]);
+  }
+  void test_literal_map() {
+    Object value = getConstantValue("{'a' : 'm', 'b' : 'n', 'c' : 'o'}");
+    EngineTestCase.assertInstanceOf(Map, value);
+    Map<Object, Object> map = (value as Map<Object, Object>);
+    JUnitTestCase.assertEquals(3, map.length);
+    JUnitTestCase.assertEquals("m", map["a"]);
+    JUnitTestCase.assertEquals("n", map["b"]);
+    JUnitTestCase.assertEquals("o", map["c"]);
+  }
+  void test_literal_null() {
+    Object value = getConstantValue("null");
+    JUnitTestCase.assertEquals(null, value);
+  }
+  void test_literal_number_double() {
+    Object value = getConstantValue("3.45");
+    EngineTestCase.assertInstanceOf(double, value);
+    JUnitTestCase.assertEquals(3.45, ((value as double)));
+  }
+  void test_literal_number_integer() {
+    Object value = getConstantValue("42");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(42, ((value as int)));
+  }
+  void test_literal_string_adjacent() {
+    Object value = getConstantValue("'abc' 'def'");
+    JUnitTestCase.assertEquals("abcdef", value);
+  }
+  void test_literal_string_interpolation_invalid() {
+    Object value = getConstantValue("'a\${f()}c'");
+    JUnitTestCase.assertEquals(ConstantEvaluator.NOT_A_CONSTANT, value);
+  }
+  void test_literal_string_interpolation_valid() {
+    Object value = getConstantValue("'a\${3}c'");
+    JUnitTestCase.assertEquals("a3c", value);
+  }
+  void test_literal_string_simple() {
+    Object value = getConstantValue("'abc'");
+    JUnitTestCase.assertEquals("abc", value);
+  }
+  void test_parenthesizedExpression() {
+    Object value = getConstantValue("('a')");
+    JUnitTestCase.assertEquals("a", value);
+  }
+  void test_unary_bitNot() {
+    Object value = getConstantValue("~42");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(~42, ((value as int)));
+  }
+  void test_unary_logicalNot() {
+    Object value = getConstantValue("!true");
+    JUnitTestCase.assertEquals(false, value);
+  }
+  void test_unary_negated_double() {
+    Object value = getConstantValue("-42.3");
+    EngineTestCase.assertInstanceOf(double, value);
+    JUnitTestCase.assertEquals(-42.3, ((value as double)));
+  }
+  void test_unary_negated_integer() {
+    Object value = getConstantValue("-42");
+    EngineTestCase.assertInstanceOf(int, value);
+    JUnitTestCase.assertEquals(-42, ((value as int)));
+  }
+  Object getConstantValue(String source) => ParserTestCase.parseExpression(source, []).accept(new ConstantEvaluator());
+  static dartSuite() {
+    _ut.group('ConstantEvaluatorTest', () {
+      _ut.test('test_binary_bitAnd', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_bitAnd);
+      });
+      _ut.test('test_binary_bitOr', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_bitOr);
+      });
+      _ut.test('test_binary_bitXor', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_bitXor);
+      });
+      _ut.test('test_binary_divide_double', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_divide_double);
+      });
+      _ut.test('test_binary_divide_integer', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_divide_integer);
+      });
+      _ut.test('test_binary_equal_boolean', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_equal_boolean);
+      });
+      _ut.test('test_binary_equal_integer', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_equal_integer);
+      });
+      _ut.test('test_binary_equal_invalidLeft', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_equal_invalidLeft);
+      });
+      _ut.test('test_binary_equal_invalidRight', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_equal_invalidRight);
+      });
+      _ut.test('test_binary_equal_string', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_equal_string);
+      });
+      _ut.test('test_binary_greaterThan', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_greaterThan);
+      });
+      _ut.test('test_binary_greaterThanOrEqual', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_greaterThanOrEqual);
+      });
+      _ut.test('test_binary_leftShift', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_leftShift);
+      });
+      _ut.test('test_binary_lessThan', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_lessThan);
+      });
+      _ut.test('test_binary_lessThanOrEqual', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_lessThanOrEqual);
+      });
+      _ut.test('test_binary_logicalAnd', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_logicalAnd);
+      });
+      _ut.test('test_binary_logicalOr', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_logicalOr);
+      });
+      _ut.test('test_binary_minus_double', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_minus_double);
+      });
+      _ut.test('test_binary_minus_integer', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_minus_integer);
+      });
+      _ut.test('test_binary_notEqual_boolean', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_notEqual_boolean);
+      });
+      _ut.test('test_binary_notEqual_integer', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_notEqual_integer);
+      });
+      _ut.test('test_binary_notEqual_invalidLeft', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_notEqual_invalidLeft);
+      });
+      _ut.test('test_binary_notEqual_invalidRight', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_notEqual_invalidRight);
+      });
+      _ut.test('test_binary_notEqual_string', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_notEqual_string);
+      });
+      _ut.test('test_binary_plus_double', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_plus_double);
+      });
+      _ut.test('test_binary_plus_integer', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_plus_integer);
+      });
+      _ut.test('test_binary_remainder_double', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_remainder_double);
+      });
+      _ut.test('test_binary_remainder_integer', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_remainder_integer);
+      });
+      _ut.test('test_binary_rightShift', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_rightShift);
+      });
+      _ut.test('test_binary_times_double', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_times_double);
+      });
+      _ut.test('test_binary_times_integer', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_times_integer);
+      });
+      _ut.test('test_binary_truncatingDivide_double', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_truncatingDivide_double);
+      });
+      _ut.test('test_binary_truncatingDivide_integer', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_binary_truncatingDivide_integer);
+      });
+      _ut.test('test_literal_boolean_false', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_boolean_false);
+      });
+      _ut.test('test_literal_boolean_true', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_boolean_true);
+      });
+      _ut.test('test_literal_list', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_list);
+      });
+      _ut.test('test_literal_map', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_map);
+      });
+      _ut.test('test_literal_null', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_null);
+      });
+      _ut.test('test_literal_number_double', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_number_double);
+      });
+      _ut.test('test_literal_number_integer', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_number_integer);
+      });
+      _ut.test('test_literal_string_adjacent', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_string_adjacent);
+      });
+      _ut.test('test_literal_string_interpolation_invalid', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_string_interpolation_invalid);
+      });
+      _ut.test('test_literal_string_interpolation_valid', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_string_interpolation_valid);
+      });
+      _ut.test('test_literal_string_simple', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_literal_string_simple);
+      });
+      _ut.test('test_parenthesizedExpression', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_parenthesizedExpression);
+      });
+      _ut.test('test_unary_bitNot', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_unary_bitNot);
+      });
+      _ut.test('test_unary_logicalNot', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_unary_logicalNot);
+      });
+      _ut.test('test_unary_negated_double', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_unary_negated_double);
+      });
+      _ut.test('test_unary_negated_integer', () {
+        final __test = new ConstantEvaluatorTest();
+        runJUnitTest(__test, __test.test_unary_negated_integer);
+      });
+    });
+  }
+}
+main() {
+  ConstantEvaluatorTest.dartSuite();
+  NodeLocatorTest.dartSuite();
+  ToSourceVisitorTest.dartSuite();
+  IndexExpressionTest.dartSuite();
+  SimpleIdentifierTest.dartSuite();
+}
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/test/generated/element_test.dart b/pkg/analyzer-experimental/test/generated/element_test.dart
new file mode 100644
index 0000000..384d332
--- /dev/null
+++ b/pkg/analyzer-experimental/test/generated/element_test.dart
@@ -0,0 +1,1840 @@
+// This code was auto-generated, is not intended to be edited, and is subject to
+// significant change. Please see the README file for more information.
+
+library engine.element_test;
+
+import 'dart:collection';
+import 'package:analyzer-experimental/src/generated/java_core.dart';
+import 'package:analyzer-experimental/src/generated/java_engine.dart';
+import 'package:analyzer-experimental/src/generated/java_junit.dart';
+import 'package:analyzer-experimental/src/generated/source.dart';
+import 'package:analyzer-experimental/src/generated/error.dart';
+import 'package:analyzer-experimental/src/generated/scanner.dart';
+import 'package:analyzer-experimental/src/generated/ast.dart' hide Annotation;
+import 'package:analyzer-experimental/src/generated/element.dart' hide Annotation;
+import 'package:analyzer-experimental/src/generated/engine.dart' show AnalysisContext, AnalysisContextImpl;
+import 'package:unittest/unittest.dart' as _ut;
+import 'test_support.dart';
+import 'scanner_test.dart' show TokenFactory;
+import 'ast_test.dart' show ASTFactory;
+
+class ElementLocationImplTest extends EngineTestCase {
+  void test_create_encoding() {
+    String encoding = "a;b;c";
+    ElementLocationImpl location = new ElementLocationImpl.con2(encoding);
+    JUnitTestCase.assertEquals(encoding, location.encoding);
+  }
+  void test_equals_equal() {
+    String encoding = "a;b;c";
+    ElementLocationImpl first = new ElementLocationImpl.con2(encoding);
+    ElementLocationImpl second = new ElementLocationImpl.con2(encoding);
+    JUnitTestCase.assertTrue(first == second);
+  }
+  void test_equals_notEqual_differentLengths() {
+    ElementLocationImpl first = new ElementLocationImpl.con2("a;b;c");
+    ElementLocationImpl second = new ElementLocationImpl.con2("a;b;c;d");
+    JUnitTestCase.assertFalse(first == second);
+  }
+  void test_equals_notEqual_notLocation() {
+    ElementLocationImpl first = new ElementLocationImpl.con2("a;b;c");
+    JUnitTestCase.assertFalse(first == "a;b;d");
+  }
+  void test_equals_notEqual_sameLengths() {
+    ElementLocationImpl first = new ElementLocationImpl.con2("a;b;c");
+    ElementLocationImpl second = new ElementLocationImpl.con2("a;b;d");
+    JUnitTestCase.assertFalse(first == second);
+  }
+  void test_getComponents() {
+    String encoding = "a;b;c";
+    ElementLocationImpl location = new ElementLocationImpl.con2(encoding);
+    List<String> components2 = location.components;
+    EngineTestCase.assertLength(3, components2);
+    JUnitTestCase.assertEquals("a", components2[0]);
+    JUnitTestCase.assertEquals("b", components2[1]);
+    JUnitTestCase.assertEquals("c", components2[2]);
+  }
+  void test_getEncoding() {
+    String encoding = "a;b;c;;d";
+    ElementLocationImpl location = new ElementLocationImpl.con2(encoding);
+    JUnitTestCase.assertEquals(encoding, location.encoding);
+  }
+  static dartSuite() {
+    _ut.group('ElementLocationImplTest', () {
+      _ut.test('test_create_encoding', () {
+        final __test = new ElementLocationImplTest();
+        runJUnitTest(__test, __test.test_create_encoding);
+      });
+      _ut.test('test_equals_equal', () {
+        final __test = new ElementLocationImplTest();
+        runJUnitTest(__test, __test.test_equals_equal);
+      });
+      _ut.test('test_equals_notEqual_differentLengths', () {
+        final __test = new ElementLocationImplTest();
+        runJUnitTest(__test, __test.test_equals_notEqual_differentLengths);
+      });
+      _ut.test('test_equals_notEqual_notLocation', () {
+        final __test = new ElementLocationImplTest();
+        runJUnitTest(__test, __test.test_equals_notEqual_notLocation);
+      });
+      _ut.test('test_equals_notEqual_sameLengths', () {
+        final __test = new ElementLocationImplTest();
+        runJUnitTest(__test, __test.test_equals_notEqual_sameLengths);
+      });
+      _ut.test('test_getComponents', () {
+        final __test = new ElementLocationImplTest();
+        runJUnitTest(__test, __test.test_getComponents);
+      });
+      _ut.test('test_getEncoding', () {
+        final __test = new ElementLocationImplTest();
+        runJUnitTest(__test, __test.test_getEncoding);
+      });
+    });
+  }
+}
+class FunctionTypeImplTest extends EngineTestCase {
+  void test_creation() {
+    JUnitTestCase.assertNotNull(new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f"))));
+  }
+  void test_getElement() {
+    FunctionElementImpl typeElement = new FunctionElementImpl.con1(ASTFactory.identifier2("f"));
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(typeElement);
+    JUnitTestCase.assertEquals(typeElement, type.element);
+  }
+  void test_getNamedParameterTypes() {
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    Map<String, Type2> types = type.namedParameterTypes;
+    EngineTestCase.assertSize2(0, types);
+  }
+  void test_getNormalParameterTypes() {
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    List<Type2> types = type.normalParameterTypes;
+    EngineTestCase.assertLength(0, types);
+  }
+  void test_getReturnType() {
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    Type2 returnType5 = type.returnType;
+    JUnitTestCase.assertEquals(VoidTypeImpl.instance, returnType5);
+  }
+  void test_getTypeArguments() {
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    List<Type2> types = type.typeArguments;
+    EngineTestCase.assertLength(0, types);
+  }
+  void test_hashCode_element() {
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    type.hashCode;
+  }
+  void test_hashCode_noElement() {
+    FunctionTypeImpl type = new FunctionTypeImpl.con1((null as ExecutableElement));
+    type.hashCode;
+  }
+  void test_isSubtypeOf_baseCase_notFunctionType() {
+    FunctionType f = ElementFactory.functionElement("f").type;
+    InterfaceType t = ElementFactory.classElement2("C", []).type;
+    JUnitTestCase.assertFalse(f.isSubtypeOf(t));
+  }
+  void test_isSubtypeOf_baseCase_null() {
+    FunctionType f = ElementFactory.functionElement("f").type;
+    JUnitTestCase.assertFalse(f.isSubtypeOf(null));
+  }
+  void test_isSubtypeOf_baseCase_self() {
+    FunctionType f = ElementFactory.functionElement("f").type;
+    JUnitTestCase.assertTrue(f.isSubtypeOf(f));
+  }
+  void test_isSubtypeOf_namedParameters_isAssignable() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["name"], <ClassElement> [a]).type;
+    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["name"], <ClassElement> [b]).type;
+    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
+    JUnitTestCase.assertTrue(s.isSubtypeOf(t));
+  }
+  void test_isSubtypeOf_namedParameters_isNotAssignable() {
+    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["name"], <ClassElement> [ElementFactory.classElement2("A", [])]).type;
+    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["name"], <ClassElement> [ElementFactory.classElement2("B", [])]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_namedParameters_namesDifferent() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["name"], <ClassElement> [a]).type;
+    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["diff"], <ClassElement> [b]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+    JUnitTestCase.assertFalse(s.isSubtypeOf(t));
+  }
+  void test_isSubtypeOf_namedParameters_orderOfParams() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["A", "B"], <ClassElement> [a, b]).type;
+    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["B", "A"], <ClassElement> [b, a]).type;
+    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_namedParameters_orderOfParams2() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["B"], <ClassElement> [b]).type;
+    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["B", "A"], <ClassElement> [b, a]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_namedParameters_orderOfParams3() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["A", "B"], <ClassElement> [a, b]).type;
+    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["B"], <ClassElement> [b]).type;
+    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_namedParameters_sHasMoreParams() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["name"], <ClassElement> [a]).type;
+    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["name", "name2"], <ClassElement> [b, b]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_namedParameters_tHasMoreParams() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement4("t", null, null, <String> ["name", "name2"], <ClassElement> [a, a]).type;
+    FunctionType s = ElementFactory.functionElement4("s", null, null, <String> ["name"], <ClassElement> [b]).type;
+    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_normalParameters_isAssignable() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [a]).type;
+    FunctionType s = ElementFactory.functionElement5("s", <ClassElement> [b]).type;
+    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
+    JUnitTestCase.assertTrue(s.isSubtypeOf(t));
+  }
+  void test_isSubtypeOf_normalParameters_isNotAssignable() {
+    FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [ElementFactory.classElement2("A", [])]).type;
+    FunctionType s = ElementFactory.functionElement5("s", <ClassElement> [ElementFactory.classElement2("B", [])]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_normalParameters_sHasMoreParams() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [a]).type;
+    FunctionType s = ElementFactory.functionElement5("s", <ClassElement> [b, b]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_normalParameters_tHasMoreParams() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [a, a]).type;
+    FunctionType s = ElementFactory.functionElement5("s", <ClassElement> [b]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_optionalParameters_isAssignable() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [a]).type;
+    FunctionType s = ElementFactory.functionElement6("s", null, <ClassElement> [b]).type;
+    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
+    JUnitTestCase.assertTrue(s.isSubtypeOf(t));
+  }
+  void test_isSubtypeOf_optionalParameters_isNotAssignable() {
+    FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [ElementFactory.classElement2("A", [])]).type;
+    FunctionType s = ElementFactory.functionElement6("s", null, <ClassElement> [ElementFactory.classElement2("B", [])]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_optionalParameters_sHasMoreParams() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [a]).type;
+    FunctionType s = ElementFactory.functionElement6("s", null, <ClassElement> [b, b]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_optionalParameters_tHasMoreParams() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [a, a]).type;
+    FunctionType s = ElementFactory.functionElement6("s", null, <ClassElement> [b]).type;
+    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_returnType_sIsVoid() {
+    FunctionType t = ElementFactory.functionElement2("t", ElementFactory.classElement2("A", [])).type;
+    FunctionType s = ElementFactory.functionElement("s").type;
+    JUnitTestCase.assertTrue(VoidTypeImpl.instance == s.returnType);
+    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_returnType_tAssignableToS() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    ClassElement b = ElementFactory.classElement("B", a.type, []);
+    FunctionType t = ElementFactory.functionElement2("t", a).type;
+    FunctionType s = ElementFactory.functionElement2("s", b).type;
+    JUnitTestCase.assertTrue(t.isSubtypeOf(s));
+    JUnitTestCase.assertTrue(s.isSubtypeOf(t));
+  }
+  void test_isSubtypeOf_returnType_tNotAssignableToS() {
+    FunctionType t = ElementFactory.functionElement2("t", ElementFactory.classElement2("A", [])).type;
+    FunctionType s = ElementFactory.functionElement2("s", ElementFactory.classElement2("B", [])).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+  }
+  void test_isSubtypeOf_wrongFunctionType_normal_named() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [a]).type;
+    FunctionType s = ElementFactory.functionElement7("s", null, <String> ["name"], <ClassElement> [a]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+    JUnitTestCase.assertFalse(s.isSubtypeOf(t));
+  }
+  void test_isSubtypeOf_wrongFunctionType_normal_optional() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    FunctionType t = ElementFactory.functionElement5("t", <ClassElement> [a]).type;
+    FunctionType s = ElementFactory.functionElement6("s", null, <ClassElement> [a]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+    JUnitTestCase.assertFalse(s.isSubtypeOf(t));
+  }
+  void test_isSubtypeOf_wrongFunctionType_optional_named() {
+    ClassElement a = ElementFactory.classElement2("A", []);
+    FunctionType t = ElementFactory.functionElement6("t", null, <ClassElement> [a]).type;
+    FunctionType s = ElementFactory.functionElement7("s", null, <String> ["name"], <ClassElement> [a]).type;
+    JUnitTestCase.assertFalse(t.isSubtypeOf(s));
+    JUnitTestCase.assertFalse(s.isSubtypeOf(t));
+  }
+  void test_setNamedParameterTypes() {
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    LinkedHashMap<String, Type2> expectedTypes = new LinkedHashMap<String, Type2>();
+    expectedTypes["a"] = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("C")));
+    type.namedParameterTypes = expectedTypes;
+    Map<String, Type2> types = type.namedParameterTypes;
+    JUnitTestCase.assertEquals(expectedTypes, types);
+  }
+  void test_setNormalParameterTypes() {
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    List<Type2> expectedTypes = <Type2> [new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("C")))];
+    type.normalParameterTypes = expectedTypes;
+    List<Type2> types = type.normalParameterTypes;
+    JUnitTestCase.assertEquals(expectedTypes, types);
+  }
+  void test_setReturnType() {
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    Type2 expectedType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("C")));
+    type.returnType = expectedType;
+    Type2 returnType6 = type.returnType;
+    JUnitTestCase.assertEquals(expectedType, returnType6);
+  }
+  void test_setTypeArguments() {
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    Type2 expectedType = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier2("C")));
+    type.typeArguments = <Type2> [expectedType];
+    List<Type2> arguments = type.typeArguments;
+    EngineTestCase.assertLength(1, arguments);
+    JUnitTestCase.assertEquals(expectedType, arguments[0]);
+  }
+  void test_substitute2_equal() {
+    FunctionTypeImpl functionType = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    TypeVariableTypeImpl parameterType = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier2("E")));
+    functionType.returnType = parameterType;
+    functionType.normalParameterTypes = <Type2> [parameterType];
+    functionType.optionalParameterTypes = <Type2> [parameterType];
+    LinkedHashMap<String, Type2> namedParameterTypes = new LinkedHashMap<String, Type2>();
+    String namedParameterName = "c";
+    namedParameterTypes[namedParameterName] = parameterType;
+    functionType.namedParameterTypes = namedParameterTypes;
+    InterfaceTypeImpl argumentType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("D")));
+    FunctionType result = functionType.substitute2(<Type2> [argumentType], <Type2> [parameterType]);
+    JUnitTestCase.assertEquals(argumentType, result.returnType);
+    List<Type2> normalParameters = result.normalParameterTypes;
+    EngineTestCase.assertLength(1, normalParameters);
+    JUnitTestCase.assertEquals(argumentType, normalParameters[0]);
+    List<Type2> optionalParameters = result.optionalParameterTypes;
+    EngineTestCase.assertLength(1, optionalParameters);
+    JUnitTestCase.assertEquals(argumentType, optionalParameters[0]);
+    Map<String, Type2> namedParameters = result.namedParameterTypes;
+    EngineTestCase.assertSize2(1, namedParameters);
+    JUnitTestCase.assertEquals(argumentType, namedParameters[namedParameterName]);
+  }
+  void test_substitute2_notEqual() {
+    FunctionTypeImpl functionType = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    Type2 returnType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("R")));
+    Type2 normalParameterType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("A")));
+    Type2 optionalParameterType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("B")));
+    Type2 namedParameterType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("C")));
+    functionType.returnType = returnType;
+    functionType.normalParameterTypes = <Type2> [normalParameterType];
+    functionType.optionalParameterTypes = <Type2> [optionalParameterType];
+    LinkedHashMap<String, Type2> namedParameterTypes = new LinkedHashMap<String, Type2>();
+    String namedParameterName = "c";
+    namedParameterTypes[namedParameterName] = namedParameterType;
+    functionType.namedParameterTypes = namedParameterTypes;
+    InterfaceTypeImpl argumentType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("D")));
+    TypeVariableTypeImpl parameterType = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier2("E")));
+    FunctionType result = functionType.substitute2(<Type2> [argumentType], <Type2> [parameterType]);
+    JUnitTestCase.assertEquals(returnType, result.returnType);
+    List<Type2> normalParameters = result.normalParameterTypes;
+    EngineTestCase.assertLength(1, normalParameters);
+    JUnitTestCase.assertEquals(normalParameterType, normalParameters[0]);
+    List<Type2> optionalParameters = result.optionalParameterTypes;
+    EngineTestCase.assertLength(1, optionalParameters);
+    JUnitTestCase.assertEquals(optionalParameterType, optionalParameters[0]);
+    Map<String, Type2> namedParameters = result.namedParameterTypes;
+    EngineTestCase.assertSize2(1, namedParameters);
+    JUnitTestCase.assertEquals(namedParameterType, namedParameters[namedParameterName]);
+  }
+  static dartSuite() {
+    _ut.group('FunctionTypeImplTest', () {
+      _ut.test('test_creation', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_creation);
+      });
+      _ut.test('test_getElement', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_getElement);
+      });
+      _ut.test('test_getNamedParameterTypes', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_getNamedParameterTypes);
+      });
+      _ut.test('test_getNormalParameterTypes', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_getNormalParameterTypes);
+      });
+      _ut.test('test_getReturnType', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_getReturnType);
+      });
+      _ut.test('test_getTypeArguments', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_getTypeArguments);
+      });
+      _ut.test('test_hashCode_element', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_hashCode_element);
+      });
+      _ut.test('test_hashCode_noElement', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_hashCode_noElement);
+      });
+      _ut.test('test_isSubtypeOf_baseCase_notFunctionType', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_baseCase_notFunctionType);
+      });
+      _ut.test('test_isSubtypeOf_baseCase_null', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_baseCase_null);
+      });
+      _ut.test('test_isSubtypeOf_baseCase_self', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_baseCase_self);
+      });
+      _ut.test('test_isSubtypeOf_namedParameters_isAssignable', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_isAssignable);
+      });
+      _ut.test('test_isSubtypeOf_namedParameters_isNotAssignable', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_isNotAssignable);
+      });
+      _ut.test('test_isSubtypeOf_namedParameters_namesDifferent', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_namesDifferent);
+      });
+      _ut.test('test_isSubtypeOf_namedParameters_orderOfParams', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_orderOfParams);
+      });
+      _ut.test('test_isSubtypeOf_namedParameters_orderOfParams2', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_orderOfParams2);
+      });
+      _ut.test('test_isSubtypeOf_namedParameters_orderOfParams3', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_orderOfParams3);
+      });
+      _ut.test('test_isSubtypeOf_namedParameters_sHasMoreParams', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_sHasMoreParams);
+      });
+      _ut.test('test_isSubtypeOf_namedParameters_tHasMoreParams', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_namedParameters_tHasMoreParams);
+      });
+      _ut.test('test_isSubtypeOf_normalParameters_isAssignable', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_normalParameters_isAssignable);
+      });
+      _ut.test('test_isSubtypeOf_normalParameters_isNotAssignable', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_normalParameters_isNotAssignable);
+      });
+      _ut.test('test_isSubtypeOf_normalParameters_sHasMoreParams', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_normalParameters_sHasMoreParams);
+      });
+      _ut.test('test_isSubtypeOf_normalParameters_tHasMoreParams', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_normalParameters_tHasMoreParams);
+      });
+      _ut.test('test_isSubtypeOf_optionalParameters_isAssignable', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_optionalParameters_isAssignable);
+      });
+      _ut.test('test_isSubtypeOf_optionalParameters_isNotAssignable', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_optionalParameters_isNotAssignable);
+      });
+      _ut.test('test_isSubtypeOf_optionalParameters_sHasMoreParams', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_optionalParameters_sHasMoreParams);
+      });
+      _ut.test('test_isSubtypeOf_optionalParameters_tHasMoreParams', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_optionalParameters_tHasMoreParams);
+      });
+      _ut.test('test_isSubtypeOf_returnType_sIsVoid', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_returnType_sIsVoid);
+      });
+      _ut.test('test_isSubtypeOf_returnType_tAssignableToS', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_returnType_tAssignableToS);
+      });
+      _ut.test('test_isSubtypeOf_returnType_tNotAssignableToS', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_returnType_tNotAssignableToS);
+      });
+      _ut.test('test_isSubtypeOf_wrongFunctionType_normal_named', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_wrongFunctionType_normal_named);
+      });
+      _ut.test('test_isSubtypeOf_wrongFunctionType_normal_optional', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_wrongFunctionType_normal_optional);
+      });
+      _ut.test('test_isSubtypeOf_wrongFunctionType_optional_named', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_wrongFunctionType_optional_named);
+      });
+      _ut.test('test_setNamedParameterTypes', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_setNamedParameterTypes);
+      });
+      _ut.test('test_setNormalParameterTypes', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_setNormalParameterTypes);
+      });
+      _ut.test('test_setReturnType', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_setReturnType);
+      });
+      _ut.test('test_setTypeArguments', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_setTypeArguments);
+      });
+      _ut.test('test_substitute2_equal', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_substitute2_equal);
+      });
+      _ut.test('test_substitute2_notEqual', () {
+        final __test = new FunctionTypeImplTest();
+        runJUnitTest(__test, __test.test_substitute2_notEqual);
+      });
+    });
+  }
+}
+class LibraryElementImplTest extends EngineTestCase {
+  void test_creation() {
+    JUnitTestCase.assertNotNull(new LibraryElementImpl(new AnalysisContextImpl(), ASTFactory.libraryIdentifier2(["l"])));
+  }
+  void test_getImportedLibraries() {
+    AnalysisContext context = new AnalysisContextImpl();
+    LibraryElementImpl library1 = ElementFactory.library(context, "l1");
+    LibraryElementImpl library2 = ElementFactory.library(context, "l2");
+    LibraryElementImpl library3 = ElementFactory.library(context, "l3");
+    LibraryElementImpl library4 = ElementFactory.library(context, "l4");
+    PrefixElement prefixA = new PrefixElementImpl(ASTFactory.identifier2("a"));
+    PrefixElement prefixB = new PrefixElementImpl(ASTFactory.identifier2("b"));
+    List<ImportElementImpl> imports = [ElementFactory.importFor(library2, null, []), ElementFactory.importFor(library2, prefixB, []), ElementFactory.importFor(library3, null, []), ElementFactory.importFor(library3, prefixA, []), ElementFactory.importFor(library3, prefixB, []), ElementFactory.importFor(library4, prefixA, [])];
+    library1.imports = imports;
+    List<LibraryElement> libraries = library1.importedLibraries;
+    EngineTestCase.assertEqualsIgnoreOrder(<LibraryElement> [library2, library3, library4], libraries);
+  }
+  void test_getPrefixes() {
+    AnalysisContext context = new AnalysisContextImpl();
+    LibraryElementImpl library17 = ElementFactory.library(context, "l1");
+    PrefixElement prefixA = new PrefixElementImpl(ASTFactory.identifier2("a"));
+    PrefixElement prefixB = new PrefixElementImpl(ASTFactory.identifier2("b"));
+    List<ImportElementImpl> imports = [ElementFactory.importFor(ElementFactory.library(context, "l2"), null, []), ElementFactory.importFor(ElementFactory.library(context, "l3"), null, []), ElementFactory.importFor(ElementFactory.library(context, "l4"), prefixA, []), ElementFactory.importFor(ElementFactory.library(context, "l5"), prefixA, []), ElementFactory.importFor(ElementFactory.library(context, "l6"), prefixB, [])];
+    library17.imports = imports;
+    List<PrefixElement> prefixes2 = library17.prefixes;
+    EngineTestCase.assertLength(2, prefixes2);
+    if (identical(prefixA, prefixes2[0])) {
+      JUnitTestCase.assertEquals(prefixB, prefixes2[1]);
+    } else {
+      JUnitTestCase.assertEquals(prefixB, prefixes2[0]);
+      JUnitTestCase.assertEquals(prefixA, prefixes2[1]);
+    }
+  }
+  void test_setImports() {
+    AnalysisContext context = new AnalysisContextImpl();
+    LibraryElementImpl library = new LibraryElementImpl(context, ASTFactory.libraryIdentifier2(["l1"]));
+    List<ImportElementImpl> expectedImports = [ElementFactory.importFor(ElementFactory.library(context, "l2"), null, []), ElementFactory.importFor(ElementFactory.library(context, "l3"), null, [])];
+    library.imports = expectedImports;
+    List<ImportElement> actualImports = library.imports;
+    EngineTestCase.assertLength(expectedImports.length, actualImports);
+    for (int i = 0; i < actualImports.length; i++) {
+      JUnitTestCase.assertEquals(expectedImports[i], actualImports[i]);
+    }
+  }
+  static dartSuite() {
+    _ut.group('LibraryElementImplTest', () {
+      _ut.test('test_creation', () {
+        final __test = new LibraryElementImplTest();
+        runJUnitTest(__test, __test.test_creation);
+      });
+      _ut.test('test_getImportedLibraries', () {
+        final __test = new LibraryElementImplTest();
+        runJUnitTest(__test, __test.test_getImportedLibraries);
+      });
+      _ut.test('test_getPrefixes', () {
+        final __test = new LibraryElementImplTest();
+        runJUnitTest(__test, __test.test_getPrefixes);
+      });
+      _ut.test('test_setImports', () {
+        final __test = new LibraryElementImplTest();
+        runJUnitTest(__test, __test.test_setImports);
+      });
+    });
+  }
+}
+/**
+ * The class {@code ElementFactory} defines utility methods used to create elements for testing
+ * purposes.
+ */
+class ElementFactory {
+  /**
+   * The element representing the class 'Object'.
+   */
+  static ClassElement _objectElement;
+  static ClassElement classElement(String typeName, InterfaceType superclassType, List<String> parameterNames) {
+    ClassElementImpl element = new ClassElementImpl(ASTFactory.identifier2(typeName));
+    element.supertype = superclassType;
+    InterfaceTypeImpl type = new InterfaceTypeImpl.con1(element);
+    element.type = type;
+    int count = parameterNames.length;
+    if (count > 0) {
+      List<TypeVariableElementImpl> typeVariables = new List<TypeVariableElementImpl>.fixedLength(count);
+      List<TypeVariableTypeImpl> typeArguments = new List<TypeVariableTypeImpl>.fixedLength(count);
+      for (int i = 0; i < count; i++) {
+        TypeVariableElementImpl variable = new TypeVariableElementImpl(ASTFactory.identifier2(parameterNames[i]));
+        typeVariables[i] = variable;
+        typeArguments[i] = new TypeVariableTypeImpl(variable);
+        variable.type = typeArguments[i];
+      }
+      element.typeVariables = typeVariables;
+      type.typeArguments = typeArguments;
+    }
+    return element;
+  }
+  static ClassElement classElement2(String typeName, List<String> parameterNames) => classElement(typeName, object.type, parameterNames);
+  static ConstructorElement constructorElement(String name) => new ConstructorElementImpl(name == null ? null : ASTFactory.identifier2(name));
+  static FieldElement fieldElement(String name, bool isStatic, bool isFinal, bool isConst, Type2 type27) {
+    FieldElementImpl field = new FieldElementImpl.con1(ASTFactory.identifier2(name));
+    field.const2 = isConst;
+    field.final2 = isFinal;
+    field.static = isStatic;
+    field.type = type27;
+    PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con1(field);
+    getter.getter = true;
+    getter.synthetic = true;
+    field.getter = getter;
+    FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
+    getterType.returnType = type27;
+    getter.type = getterType;
+    if (!isConst && !isFinal) {
+      PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con1(field);
+      setter.setter = true;
+      setter.synthetic = true;
+      field.setter = setter;
+      FunctionTypeImpl setterType = new FunctionTypeImpl.con1(getter);
+      setterType.normalParameterTypes = <Type2> [type27];
+      setterType.returnType = VoidTypeImpl.instance;
+      setter.type = setterType;
+    }
+    return field;
+  }
+  static FunctionElement functionElement(String functionName) => functionElement4(functionName, null, null, null, null);
+  static FunctionElement functionElement2(String functionName, ClassElement returnElement) => functionElement3(functionName, returnElement, null, null);
+  static FunctionElement functionElement3(String functionName, ClassElement returnElement, List<ClassElement> normalParameters, List<ClassElement> optionalParameters) {
+    FunctionElementImpl functionElement = new FunctionElementImpl.con1(ASTFactory.identifier2(functionName));
+    FunctionTypeImpl functionType = new FunctionTypeImpl.con1(functionElement);
+    functionElement.type = functionType;
+    if (returnElement != null) {
+      functionType.returnType = returnElement.type;
+    }
+    int count = normalParameters == null ? 0 : normalParameters.length;
+    if (count > 0) {
+      List<InterfaceType> normalParameterTypes = new List<InterfaceType>.fixedLength(count);
+      for (int i = 0; i < count; i++) {
+        normalParameterTypes[i] = normalParameters[i].type;
+      }
+      functionType.normalParameterTypes = normalParameterTypes;
+    }
+    count = optionalParameters == null ? 0 : optionalParameters.length;
+    if (count > 0) {
+      List<InterfaceType> optionalParameterTypes = new List<InterfaceType>.fixedLength(count);
+      for (int i = 0; i < count; i++) {
+        optionalParameterTypes[i] = optionalParameters[i].type;
+      }
+      functionType.optionalParameterTypes = optionalParameterTypes;
+    }
+    return functionElement;
+  }
+  static FunctionElement functionElement4(String functionName, ClassElement returnElement, List<ClassElement> normalParameters, List<String> names, List<ClassElement> namedParameters) {
+    FunctionElementImpl functionElement = new FunctionElementImpl.con1(ASTFactory.identifier2(functionName));
+    FunctionTypeImpl functionType = new FunctionTypeImpl.con1(functionElement);
+    functionElement.type = functionType;
+    if (returnElement != null) {
+      functionType.returnType = returnElement.type;
+    }
+    int count = normalParameters == null ? 0 : normalParameters.length;
+    if (count > 0) {
+      List<InterfaceType> normalParameterTypes = new List<InterfaceType>.fixedLength(count);
+      for (int i = 0; i < count; i++) {
+        normalParameterTypes[i] = normalParameters[i].type;
+      }
+      functionType.normalParameterTypes = normalParameterTypes;
+    }
+    if (names != null && names.length > 0 && names.length == namedParameters.length) {
+      LinkedHashMap<String, Type2> map = new LinkedHashMap<String, Type2>();
+      for (int i = 0; i < names.length; i++) {
+        map[names[i]] = namedParameters[i].type;
+      }
+      functionType.namedParameterTypes = map;
+    } else if (names != null) {
+      throw new IllegalStateException("The passed String[] and ClassElement[] arrays had different lengths.");
+    }
+    return functionElement;
+  }
+  static FunctionElement functionElement5(String functionName, List<ClassElement> normalParameters) => functionElement3(functionName, null, normalParameters, null);
+  static FunctionElement functionElement6(String functionName, List<ClassElement> normalParameters, List<ClassElement> optionalParameters) => functionElement3(functionName, null, normalParameters, optionalParameters);
+  static FunctionElement functionElement7(String functionName, List<ClassElement> normalParameters, List<String> names, List<ClassElement> namedParameters) => functionElement4(functionName, null, normalParameters, names, namedParameters);
+  static ClassElement get object {
+    if (_objectElement == null) {
+      _objectElement = classElement("Object", (null as InterfaceType), []);
+    }
+    return _objectElement;
+  }
+  static PropertyAccessorElement getterElement(String name, bool isStatic, Type2 type28) {
+    FieldElementImpl field = new FieldElementImpl.con1(ASTFactory.identifier2(name));
+    field.static = isStatic;
+    field.synthetic = true;
+    field.type = type28;
+    PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con1(field);
+    getter.getter = true;
+    field.getter = getter;
+    FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
+    getterType.returnType = type28;
+    getter.type = getterType;
+    return getter;
+  }
+  static ImportElementImpl importFor(LibraryElement importedLibrary4, PrefixElement prefix12, List<NamespaceCombinator> combinators4) {
+    ImportElementImpl spec = new ImportElementImpl();
+    spec.importedLibrary = importedLibrary4;
+    spec.prefix = prefix12;
+    spec.combinators = combinators4;
+    return spec;
+  }
+  static LibraryElementImpl library(AnalysisContext context, String libraryName) {
+    String fileName = "${libraryName}.dart";
+    FileBasedSource source = new FileBasedSource.con1(null, createFile(fileName));
+    CompilationUnitElementImpl unit = new CompilationUnitElementImpl(fileName);
+    unit.source = source;
+    LibraryElementImpl library = new LibraryElementImpl(context, ASTFactory.libraryIdentifier2([libraryName]));
+    library.definingCompilationUnit = unit;
+    return library;
+  }
+  static MethodElement methodElement(String methodName, Type2 returnType9, List<Type2> argumentTypes) {
+    MethodElementImpl method = new MethodElementImpl.con1(ASTFactory.identifier2(methodName));
+    int count = argumentTypes.length;
+    List<ParameterElement> parameters = new List<ParameterElement>.fixedLength(count);
+    for (int i = 0; i < count; i++) {
+      ParameterElementImpl parameter = new ParameterElementImpl(ASTFactory.identifier2("a${i}"));
+      parameter.type = argumentTypes[i];
+      parameters[i] = parameter;
+    }
+    method.parameters = parameters;
+    FunctionTypeImpl methodType = new FunctionTypeImpl.con1(method);
+    methodType.normalParameterTypes = argumentTypes;
+    methodType.returnType = returnType9;
+    method.type = methodType;
+    return method;
+  }
+  static PropertyAccessorElement setterElement(String name, bool isStatic, Type2 type29) {
+    FieldElementImpl field = new FieldElementImpl.con1(ASTFactory.identifier2(name));
+    field.static = isStatic;
+    field.synthetic = true;
+    field.type = type29;
+    PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con1(field);
+    getter.getter = true;
+    field.getter = getter;
+    FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
+    getterType.returnType = type29;
+    getter.type = getterType;
+    PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con1(field);
+    setter.setter = true;
+    setter.synthetic = true;
+    field.setter = setter;
+    FunctionTypeImpl setterType = new FunctionTypeImpl.con1(getter);
+    setterType.normalParameterTypes = <Type2> [type29];
+    setterType.returnType = VoidTypeImpl.instance;
+    setter.type = setterType;
+    return setter;
+  }
+  static VariableElement variableElement(String name) => new VariableElementImpl.con2(name, -1);
+  /**
+   * Prevent the creation of instances of this class.
+   */
+  ElementFactory() {
+  }
+}
+class ElementImplTest extends EngineTestCase {
+  void test_isAccessibleIn_private_differentLibrary() {
+    AnalysisContextImpl context = new AnalysisContextImpl();
+    LibraryElementImpl library1 = ElementFactory.library(context, "lib1");
+    ClassElement classElement = ElementFactory.classElement2("_C", []);
+    ((library1.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classElement];
+    LibraryElementImpl library2 = ElementFactory.library(context, "lib2");
+    JUnitTestCase.assertFalse(classElement.isAccessibleIn(library2));
+  }
+  void test_isAccessibleIn_private_sameLibrary() {
+    LibraryElementImpl library15 = ElementFactory.library(new AnalysisContextImpl(), "lib");
+    ClassElement classElement = ElementFactory.classElement2("_C", []);
+    ((library15.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classElement];
+    JUnitTestCase.assertTrue(classElement.isAccessibleIn(library15));
+  }
+  void test_isAccessibleIn_public_differentLibrary() {
+    AnalysisContextImpl context = new AnalysisContextImpl();
+    LibraryElementImpl library1 = ElementFactory.library(context, "lib1");
+    ClassElement classElement = ElementFactory.classElement2("C", []);
+    ((library1.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classElement];
+    LibraryElementImpl library2 = ElementFactory.library(context, "lib2");
+    JUnitTestCase.assertTrue(classElement.isAccessibleIn(library2));
+  }
+  void test_isAccessibleIn_public_sameLibrary() {
+    LibraryElementImpl library16 = ElementFactory.library(new AnalysisContextImpl(), "lib");
+    ClassElement classElement = ElementFactory.classElement2("C", []);
+    ((library16.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classElement];
+    JUnitTestCase.assertTrue(classElement.isAccessibleIn(library16));
+  }
+  static dartSuite() {
+    _ut.group('ElementImplTest', () {
+      _ut.test('test_isAccessibleIn_private_differentLibrary', () {
+        final __test = new ElementImplTest();
+        runJUnitTest(__test, __test.test_isAccessibleIn_private_differentLibrary);
+      });
+      _ut.test('test_isAccessibleIn_private_sameLibrary', () {
+        final __test = new ElementImplTest();
+        runJUnitTest(__test, __test.test_isAccessibleIn_private_sameLibrary);
+      });
+      _ut.test('test_isAccessibleIn_public_differentLibrary', () {
+        final __test = new ElementImplTest();
+        runJUnitTest(__test, __test.test_isAccessibleIn_public_differentLibrary);
+      });
+      _ut.test('test_isAccessibleIn_public_sameLibrary', () {
+        final __test = new ElementImplTest();
+        runJUnitTest(__test, __test.test_isAccessibleIn_public_sameLibrary);
+      });
+    });
+  }
+}
+class InterfaceTypeImplTest extends EngineTestCase {
+  void test_computeLongestInheritancePathToObject_multipleInterfacePaths() {
+    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl elementB = (ElementFactory.classElement2("B", []) as ClassElementImpl);
+    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    ClassElementImpl elementD = (ElementFactory.classElement2("D", []) as ClassElementImpl);
+    ClassElementImpl elementE = (ElementFactory.classElement2("E", []) as ClassElementImpl);
+    elementB.interfaces = <InterfaceType> [elementA.type];
+    elementC.interfaces = <InterfaceType> [elementA.type];
+    elementD.interfaces = <InterfaceType> [elementC.type];
+    elementE.interfaces = <InterfaceType> [elementB.type, elementD.type];
+    JUnitTestCase.assertEquals(2, InterfaceTypeImpl.computeLongestInheritancePathToObject(elementB.type));
+    JUnitTestCase.assertEquals(4, InterfaceTypeImpl.computeLongestInheritancePathToObject(elementE.type));
+  }
+  void test_computeLongestInheritancePathToObject_multipleSuperclassPaths() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
+    ClassElement elementC = ElementFactory.classElement("C", elementA.type, []);
+    ClassElement elementD = ElementFactory.classElement("D", elementC.type, []);
+    ClassElementImpl elementE = (ElementFactory.classElement("E", elementB.type, []) as ClassElementImpl);
+    elementE.interfaces = <InterfaceType> [elementD.type];
+    JUnitTestCase.assertEquals(2, InterfaceTypeImpl.computeLongestInheritancePathToObject(elementB.type));
+    JUnitTestCase.assertEquals(4, InterfaceTypeImpl.computeLongestInheritancePathToObject(elementE.type));
+  }
+  void test_computeLongestInheritancePathToObject_object() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    InterfaceType object = elementA.supertype;
+    JUnitTestCase.assertEquals(0, InterfaceTypeImpl.computeLongestInheritancePathToObject(object));
+  }
+  void test_computeLongestInheritancePathToObject_singleInterfacePath() {
+    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl elementB = (ElementFactory.classElement2("B", []) as ClassElementImpl);
+    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    elementB.interfaces = <InterfaceType> [elementA.type];
+    elementC.interfaces = <InterfaceType> [elementB.type];
+    JUnitTestCase.assertEquals(1, InterfaceTypeImpl.computeLongestInheritancePathToObject(elementA.type));
+    JUnitTestCase.assertEquals(2, InterfaceTypeImpl.computeLongestInheritancePathToObject(elementB.type));
+    JUnitTestCase.assertEquals(3, InterfaceTypeImpl.computeLongestInheritancePathToObject(elementC.type));
+  }
+  void test_computeLongestInheritancePathToObject_singleSuperclassPath() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
+    ClassElement elementC = ElementFactory.classElement("C", elementB.type, []);
+    JUnitTestCase.assertEquals(1, InterfaceTypeImpl.computeLongestInheritancePathToObject(elementA.type));
+    JUnitTestCase.assertEquals(2, InterfaceTypeImpl.computeLongestInheritancePathToObject(elementB.type));
+    JUnitTestCase.assertEquals(3, InterfaceTypeImpl.computeLongestInheritancePathToObject(elementC.type));
+  }
+  void test_computeSuperinterfaceSet_multipleInterfacePaths() {
+    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl elementB = (ElementFactory.classElement2("B", []) as ClassElementImpl);
+    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    ClassElementImpl elementD = (ElementFactory.classElement2("D", []) as ClassElementImpl);
+    ClassElementImpl elementE = (ElementFactory.classElement2("E", []) as ClassElementImpl);
+    elementB.interfaces = <InterfaceType> [elementA.type];
+    elementC.interfaces = <InterfaceType> [elementA.type];
+    elementD.interfaces = <InterfaceType> [elementC.type];
+    elementE.interfaces = <InterfaceType> [elementB.type, elementD.type];
+    Set<InterfaceType> superinterfacesOfD = InterfaceTypeImpl.computeSuperinterfaceSet(elementD.type);
+    JUnitTestCase.assertNotNull(superinterfacesOfD);
+    JUnitTestCase.assertTrue(superinterfacesOfD.contains(ElementFactory.object.type));
+    JUnitTestCase.assertTrue(superinterfacesOfD.contains(elementA.type));
+    JUnitTestCase.assertTrue(superinterfacesOfD.contains(elementC.type));
+    JUnitTestCase.assertEquals(3, superinterfacesOfD.length);
+    Set<InterfaceType> superinterfacesOfE = InterfaceTypeImpl.computeSuperinterfaceSet(elementE.type);
+    JUnitTestCase.assertNotNull(superinterfacesOfE);
+    JUnitTestCase.assertTrue(superinterfacesOfE.contains(ElementFactory.object.type));
+    JUnitTestCase.assertTrue(superinterfacesOfE.contains(elementA.type));
+    JUnitTestCase.assertTrue(superinterfacesOfE.contains(elementB.type));
+    JUnitTestCase.assertTrue(superinterfacesOfE.contains(elementC.type));
+    JUnitTestCase.assertTrue(superinterfacesOfE.contains(elementD.type));
+    JUnitTestCase.assertEquals(5, superinterfacesOfE.length);
+  }
+  void test_computeSuperinterfaceSet_multipleSuperclassPaths() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
+    ClassElement elementC = ElementFactory.classElement("C", elementA.type, []);
+    ClassElement elementD = ElementFactory.classElement("D", elementC.type, []);
+    ClassElementImpl elementE = (ElementFactory.classElement("E", elementB.type, []) as ClassElementImpl);
+    elementE.interfaces = <InterfaceType> [elementD.type];
+    Set<InterfaceType> superinterfacesOfD = InterfaceTypeImpl.computeSuperinterfaceSet(elementD.type);
+    JUnitTestCase.assertNotNull(superinterfacesOfD);
+    JUnitTestCase.assertTrue(superinterfacesOfD.contains(ElementFactory.object.type));
+    JUnitTestCase.assertTrue(superinterfacesOfD.contains(elementA.type));
+    JUnitTestCase.assertTrue(superinterfacesOfD.contains(elementC.type));
+    JUnitTestCase.assertEquals(3, superinterfacesOfD.length);
+    Set<InterfaceType> superinterfacesOfE = InterfaceTypeImpl.computeSuperinterfaceSet(elementE.type);
+    JUnitTestCase.assertNotNull(superinterfacesOfE);
+    JUnitTestCase.assertTrue(superinterfacesOfE.contains(ElementFactory.object.type));
+    JUnitTestCase.assertTrue(superinterfacesOfE.contains(elementA.type));
+    JUnitTestCase.assertTrue(superinterfacesOfE.contains(elementB.type));
+    JUnitTestCase.assertTrue(superinterfacesOfE.contains(elementC.type));
+    JUnitTestCase.assertTrue(superinterfacesOfE.contains(elementD.type));
+    JUnitTestCase.assertEquals(5, superinterfacesOfE.length);
+  }
+  void test_computeSuperinterfaceSet_singleInterfacePath() {
+    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl elementB = (ElementFactory.classElement2("B", []) as ClassElementImpl);
+    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    elementB.interfaces = <InterfaceType> [elementA.type];
+    elementC.interfaces = <InterfaceType> [elementB.type];
+    Set<InterfaceType> superinterfacesOfA = InterfaceTypeImpl.computeSuperinterfaceSet(elementA.type);
+    JUnitTestCase.assertNotNull(superinterfacesOfA);
+    JUnitTestCase.assertTrue(superinterfacesOfA.contains(ElementFactory.object.type));
+    JUnitTestCase.assertEquals(1, superinterfacesOfA.length);
+    Set<InterfaceType> superinterfacesOfB = InterfaceTypeImpl.computeSuperinterfaceSet(elementB.type);
+    JUnitTestCase.assertNotNull(superinterfacesOfB);
+    JUnitTestCase.assertTrue(superinterfacesOfB.contains(ElementFactory.object.type));
+    JUnitTestCase.assertTrue(superinterfacesOfB.contains(elementA.type));
+    JUnitTestCase.assertEquals(2, superinterfacesOfB.length);
+    Set<InterfaceType> superinterfacesOfC = InterfaceTypeImpl.computeSuperinterfaceSet(elementC.type);
+    JUnitTestCase.assertNotNull(superinterfacesOfC);
+    JUnitTestCase.assertTrue(superinterfacesOfC.contains(ElementFactory.object.type));
+    JUnitTestCase.assertTrue(superinterfacesOfC.contains(elementA.type));
+    JUnitTestCase.assertTrue(superinterfacesOfC.contains(elementB.type));
+    JUnitTestCase.assertEquals(3, superinterfacesOfC.length);
+  }
+  void test_computeSuperinterfaceSet_singleSuperclassPath() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
+    ClassElement elementC = ElementFactory.classElement("C", elementB.type, []);
+    Set<InterfaceType> superinterfacesOfA = InterfaceTypeImpl.computeSuperinterfaceSet(elementA.type);
+    JUnitTestCase.assertNotNull(superinterfacesOfA);
+    JUnitTestCase.assertTrue(superinterfacesOfA.contains(ElementFactory.object.type));
+    JUnitTestCase.assertEquals(1, superinterfacesOfA.length);
+    Set<InterfaceType> superinterfacesOfB = InterfaceTypeImpl.computeSuperinterfaceSet(elementB.type);
+    JUnitTestCase.assertNotNull(superinterfacesOfB);
+    JUnitTestCase.assertTrue(superinterfacesOfB.contains(ElementFactory.object.type));
+    JUnitTestCase.assertTrue(superinterfacesOfB.contains(elementA.type));
+    JUnitTestCase.assertEquals(2, superinterfacesOfB.length);
+    Set<InterfaceType> superinterfacesOfC = InterfaceTypeImpl.computeSuperinterfaceSet(elementC.type);
+    JUnitTestCase.assertNotNull(superinterfacesOfC);
+    JUnitTestCase.assertTrue(superinterfacesOfC.contains(ElementFactory.object.type));
+    JUnitTestCase.assertTrue(superinterfacesOfC.contains(elementA.type));
+    JUnitTestCase.assertTrue(superinterfacesOfC.contains(elementB.type));
+    JUnitTestCase.assertEquals(3, superinterfacesOfC.length);
+  }
+  void test_creation() {
+    JUnitTestCase.assertNotNull(new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("A"))));
+  }
+  void test_getElement() {
+    ClassElementImpl typeElement = new ClassElementImpl(ASTFactory.identifier2("A"));
+    InterfaceTypeImpl type = new InterfaceTypeImpl.con1(typeElement);
+    JUnitTestCase.assertEquals(typeElement, type.element);
+  }
+  void test_getLeastUpperBound_directInterfaceCase() {
+    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl elementB = (ElementFactory.classElement2("B", []) as ClassElementImpl);
+    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeB = elementB.type;
+    InterfaceType typeC = elementC.type;
+    elementB.interfaces = <InterfaceType> [typeA];
+    elementC.interfaces = <InterfaceType> [typeB];
+    JUnitTestCase.assertEquals(typeB, typeB.getLeastUpperBound(typeC));
+    JUnitTestCase.assertEquals(typeB, typeC.getLeastUpperBound(typeB));
+  }
+  void test_getLeastUpperBound_directSubclassCase() {
+    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl elementB = (ElementFactory.classElement("B", elementA.type, []) as ClassElementImpl);
+    ClassElementImpl elementC = (ElementFactory.classElement("C", elementB.type, []) as ClassElementImpl);
+    InterfaceType typeB = elementB.type;
+    InterfaceType typeC = elementC.type;
+    JUnitTestCase.assertEquals(typeB, typeB.getLeastUpperBound(typeC));
+    JUnitTestCase.assertEquals(typeB, typeC.getLeastUpperBound(typeB));
+  }
+  void test_getLeastUpperBound_functionType() {
+    Type2 interfaceType = ElementFactory.classElement2("A", []).type;
+    FunctionTypeImpl functionType = new FunctionTypeImpl.con1(new FunctionElementImpl.con1(ASTFactory.identifier2("f")));
+    JUnitTestCase.assertNull(interfaceType.getLeastUpperBound(functionType));
+  }
+  void test_getLeastUpperBound_mixinCase() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
+    ClassElement elementC = ElementFactory.classElement("C", elementA.type, []);
+    ClassElementImpl elementD = (ElementFactory.classElement("D", elementB.type, []) as ClassElementImpl);
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeC = elementC.type;
+    InterfaceType typeD = elementD.type;
+    elementD.mixins = <InterfaceType> [ElementFactory.classElement2("M", []).type, ElementFactory.classElement2("N", []).type, ElementFactory.classElement2("O", []).type, ElementFactory.classElement2("P", []).type];
+    JUnitTestCase.assertEquals(typeA, typeD.getLeastUpperBound(typeC));
+    JUnitTestCase.assertEquals(typeA, typeC.getLeastUpperBound(typeD));
+  }
+  void test_getLeastUpperBound_null() {
+    Type2 interfaceType = ElementFactory.classElement2("A", []).type;
+    JUnitTestCase.assertNull(interfaceType.getLeastUpperBound(null));
+  }
+  void test_getLeastUpperBound_object() {
+    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl elementB = (ElementFactory.classElement2("B", []) as ClassElementImpl);
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeB = elementB.type;
+    Type2 typeObject = typeA.element.supertype;
+    JUnitTestCase.assertNull(((typeObject.element as ClassElement)).supertype);
+    JUnitTestCase.assertEquals(typeObject, typeB.element.supertype);
+    JUnitTestCase.assertEquals(typeObject, typeA.getLeastUpperBound(typeB));
+  }
+  void test_getLeastUpperBound_self() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    InterfaceType typeA = elementA.type;
+    JUnitTestCase.assertEquals(typeA, typeA.getLeastUpperBound(typeA));
+  }
+  void test_getLeastUpperBound_sharedSuperclass1() {
+    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl elementB = (ElementFactory.classElement("B", elementA.type, []) as ClassElementImpl);
+    ClassElementImpl elementC = (ElementFactory.classElement("C", elementA.type, []) as ClassElementImpl);
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeB = elementB.type;
+    InterfaceType typeC = elementC.type;
+    JUnitTestCase.assertEquals(typeA, typeB.getLeastUpperBound(typeC));
+    JUnitTestCase.assertEquals(typeA, typeC.getLeastUpperBound(typeB));
+  }
+  void test_getLeastUpperBound_sharedSuperclass2() {
+    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl elementB = (ElementFactory.classElement("B", elementA.type, []) as ClassElementImpl);
+    ClassElementImpl elementC = (ElementFactory.classElement("C", elementA.type, []) as ClassElementImpl);
+    ClassElementImpl elementD = (ElementFactory.classElement("D", elementC.type, []) as ClassElementImpl);
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeB = elementB.type;
+    InterfaceType typeD = elementD.type;
+    JUnitTestCase.assertEquals(typeA, typeB.getLeastUpperBound(typeD));
+    JUnitTestCase.assertEquals(typeA, typeD.getLeastUpperBound(typeB));
+  }
+  void test_getLeastUpperBound_sharedSuperclass3() {
+    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl elementB = (ElementFactory.classElement("B", elementA.type, []) as ClassElementImpl);
+    ClassElementImpl elementC = (ElementFactory.classElement("C", elementB.type, []) as ClassElementImpl);
+    ClassElementImpl elementD = (ElementFactory.classElement("D", elementB.type, []) as ClassElementImpl);
+    InterfaceType typeB = elementB.type;
+    InterfaceType typeC = elementC.type;
+    InterfaceType typeD = elementD.type;
+    JUnitTestCase.assertEquals(typeB, typeC.getLeastUpperBound(typeD));
+    JUnitTestCase.assertEquals(typeB, typeD.getLeastUpperBound(typeC));
+  }
+  void test_getLeastUpperBound_sharedSuperclass4() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementA2 = ElementFactory.classElement2("A2", []);
+    ClassElement elementA3 = ElementFactory.classElement2("A3", []);
+    ClassElementImpl elementB = (ElementFactory.classElement("B", elementA.type, []) as ClassElementImpl);
+    ClassElementImpl elementC = (ElementFactory.classElement("C", elementA.type, []) as ClassElementImpl);
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeA2 = elementA2.type;
+    InterfaceType typeA3 = elementA3.type;
+    InterfaceType typeB = elementB.type;
+    InterfaceType typeC = elementC.type;
+    elementB.interfaces = <InterfaceType> [typeA2];
+    elementC.interfaces = <InterfaceType> [typeA3];
+    JUnitTestCase.assertEquals(typeA, typeB.getLeastUpperBound(typeC));
+    JUnitTestCase.assertEquals(typeA, typeC.getLeastUpperBound(typeB));
+  }
+  void test_getLeastUpperBound_sharedSuperinterface1() {
+    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl elementB = (ElementFactory.classElement2("B", []) as ClassElementImpl);
+    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeB = elementB.type;
+    InterfaceType typeC = elementC.type;
+    elementB.interfaces = <InterfaceType> [typeA];
+    elementC.interfaces = <InterfaceType> [typeA];
+    JUnitTestCase.assertEquals(typeA, typeB.getLeastUpperBound(typeC));
+    JUnitTestCase.assertEquals(typeA, typeC.getLeastUpperBound(typeB));
+  }
+  void test_getLeastUpperBound_sharedSuperinterface2() {
+    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl elementB = (ElementFactory.classElement2("B", []) as ClassElementImpl);
+    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    ClassElementImpl elementD = (ElementFactory.classElement2("D", []) as ClassElementImpl);
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeB = elementB.type;
+    InterfaceType typeC = elementC.type;
+    InterfaceType typeD = elementD.type;
+    elementB.interfaces = <InterfaceType> [typeA];
+    elementC.interfaces = <InterfaceType> [typeA];
+    elementD.interfaces = <InterfaceType> [typeC];
+    JUnitTestCase.assertEquals(typeA, typeB.getLeastUpperBound(typeD));
+    JUnitTestCase.assertEquals(typeA, typeD.getLeastUpperBound(typeB));
+  }
+  void test_getLeastUpperBound_sharedSuperinterface3() {
+    ClassElementImpl elementA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ClassElementImpl elementB = (ElementFactory.classElement2("B", []) as ClassElementImpl);
+    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    ClassElementImpl elementD = (ElementFactory.classElement2("D", []) as ClassElementImpl);
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeB = elementB.type;
+    InterfaceType typeC = elementC.type;
+    InterfaceType typeD = elementD.type;
+    elementB.interfaces = <InterfaceType> [typeA];
+    elementC.interfaces = <InterfaceType> [typeB];
+    elementD.interfaces = <InterfaceType> [typeB];
+    JUnitTestCase.assertEquals(typeB, typeC.getLeastUpperBound(typeD));
+    JUnitTestCase.assertEquals(typeB, typeD.getLeastUpperBound(typeC));
+  }
+  void test_getLeastUpperBound_sharedSuperinterface4() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementA2 = ElementFactory.classElement2("A2", []);
+    ClassElement elementA3 = ElementFactory.classElement2("A3", []);
+    ClassElementImpl elementB = (ElementFactory.classElement2("B", []) as ClassElementImpl);
+    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeA2 = elementA2.type;
+    InterfaceType typeA3 = elementA3.type;
+    InterfaceType typeB = elementB.type;
+    InterfaceType typeC = elementC.type;
+    elementB.interfaces = <InterfaceType> [typeA, typeA2];
+    elementC.interfaces = <InterfaceType> [typeA, typeA3];
+    JUnitTestCase.assertEquals(typeA, typeB.getLeastUpperBound(typeC));
+    JUnitTestCase.assertEquals(typeA, typeC.getLeastUpperBound(typeB));
+  }
+  void test_getTypeArguments() {
+    InterfaceTypeImpl type = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("A")));
+    EngineTestCase.assertLength(0, type.typeArguments);
+  }
+  void test_isDirectSupertypeOf_extends() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
+    InterfaceTypeImpl typeA = new InterfaceTypeImpl.con1(elementA);
+    InterfaceTypeImpl typeB = new InterfaceTypeImpl.con1(elementB);
+    JUnitTestCase.assertTrue(typeA.isDirectSupertypeOf(typeB));
+  }
+  void test_isDirectSupertypeOf_false() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement2("B", []);
+    ClassElement elementC = ElementFactory.classElement("C", elementB.type, []);
+    InterfaceTypeImpl typeA = new InterfaceTypeImpl.con1(elementA);
+    InterfaceTypeImpl typeC = new InterfaceTypeImpl.con1(elementC);
+    JUnitTestCase.assertFalse(typeA.isDirectSupertypeOf(typeC));
+  }
+  void test_isDirectSupertypeOf_implements() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement2("B", []);
+    ((elementB as ClassElementImpl)).interfaces = <InterfaceType> [elementA.type];
+    InterfaceTypeImpl typeA = new InterfaceTypeImpl.con1(elementA);
+    InterfaceTypeImpl typeB = new InterfaceTypeImpl.con1(elementB);
+    JUnitTestCase.assertTrue(typeA.isDirectSupertypeOf(typeB));
+  }
+  void test_isDirectSupertypeOf_with() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement2("B", []);
+    ((elementB as ClassElementImpl)).mixins = <InterfaceType> [elementA.type];
+    InterfaceTypeImpl typeA = new InterfaceTypeImpl.con1(elementA);
+    InterfaceTypeImpl typeB = new InterfaceTypeImpl.con1(elementB);
+    JUnitTestCase.assertTrue(typeA.isDirectSupertypeOf(typeB));
+  }
+  void test_isMoreSpecificThan_bottom() {
+    Type2 type19 = ElementFactory.classElement2("A", []).type;
+    JUnitTestCase.assertTrue(BottomTypeImpl.instance.isMoreSpecificThan(type19));
+  }
+  void test_isMoreSpecificThan_covariance() {
+    ClassElement elementA = ElementFactory.classElement2("A", ["E"]);
+    ClassElement elementI = ElementFactory.classElement2("I", []);
+    ClassElement elementJ = ElementFactory.classElement("J", elementI.type, []);
+    InterfaceTypeImpl typeAI = new InterfaceTypeImpl.con1(elementA);
+    InterfaceTypeImpl typeAJ = new InterfaceTypeImpl.con1(elementA);
+    typeAI.typeArguments = <Type2> [elementI.type];
+    typeAJ.typeArguments = <Type2> [elementJ.type];
+    JUnitTestCase.assertTrue(typeAJ.isMoreSpecificThan(typeAI));
+    JUnitTestCase.assertFalse(typeAI.isMoreSpecificThan(typeAJ));
+  }
+  void test_isMoreSpecificThan_directSupertype() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeB = elementB.type;
+    JUnitTestCase.assertTrue(typeB.isMoreSpecificThan(typeA));
+    JUnitTestCase.assertFalse(typeA.isMoreSpecificThan(typeB));
+  }
+  void test_isMoreSpecificThan_dynamic() {
+    InterfaceType type20 = ElementFactory.classElement2("A", []).type;
+    JUnitTestCase.assertTrue(type20.isMoreSpecificThan(DynamicTypeImpl.instance));
+  }
+  void test_isMoreSpecificThan_indirectSupertype() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
+    ClassElement elementC = ElementFactory.classElement("C", elementB.type, []);
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeC = elementC.type;
+    JUnitTestCase.assertTrue(typeC.isMoreSpecificThan(typeA));
+  }
+  void test_isMoreSpecificThan_self() {
+    InterfaceType type21 = ElementFactory.classElement2("A", []).type;
+    JUnitTestCase.assertTrue(type21.isMoreSpecificThan(type21));
+  }
+  void test_isSubtypeOf_directSubtype() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeB = elementB.type;
+    JUnitTestCase.assertTrue(typeB.isSubtypeOf(typeA));
+    JUnitTestCase.assertFalse(typeA.isSubtypeOf(typeB));
+  }
+  void test_isSubtypeOf_dynamic() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    InterfaceType typeA = elementA.type;
+    Type2 dynamicType = DynamicTypeImpl.instance;
+    JUnitTestCase.assertFalse(dynamicType.isSubtypeOf(typeA));
+    JUnitTestCase.assertTrue(typeA.isSubtypeOf(dynamicType));
+  }
+  void test_isSubtypeOf_indirectSubtype() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
+    ClassElement elementC = ElementFactory.classElement("C", elementB.type, []);
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeC = elementC.type;
+    JUnitTestCase.assertTrue(typeC.isSubtypeOf(typeA));
+    JUnitTestCase.assertFalse(typeA.isSubtypeOf(typeC));
+  }
+  void test_isSubtypeOf_interface() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
+    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    InterfaceType typeObject = elementA.supertype;
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeB = elementB.type;
+    InterfaceType typeC = elementC.type;
+    elementC.interfaces = <InterfaceType> [typeB];
+    JUnitTestCase.assertTrue(typeC.isSubtypeOf(typeB));
+    JUnitTestCase.assertTrue(typeC.isSubtypeOf(typeObject));
+    JUnitTestCase.assertTrue(typeC.isSubtypeOf(typeA));
+    JUnitTestCase.assertFalse(typeA.isSubtypeOf(typeC));
+  }
+  void test_isSubtypeOf_mixins() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
+    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    InterfaceType typeObject = elementA.supertype;
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeB = elementB.type;
+    InterfaceType typeC = elementC.type;
+    elementC.mixins = <InterfaceType> [typeB];
+    JUnitTestCase.assertTrue(typeC.isSubtypeOf(typeB));
+    JUnitTestCase.assertTrue(typeC.isSubtypeOf(typeObject));
+    JUnitTestCase.assertFalse(typeC.isSubtypeOf(typeA));
+    JUnitTestCase.assertFalse(typeA.isSubtypeOf(typeC));
+  }
+  void test_isSubtypeOf_object() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeObject = elementA.supertype;
+    JUnitTestCase.assertTrue(typeA.isSubtypeOf(typeObject));
+    JUnitTestCase.assertFalse(typeObject.isSubtypeOf(typeA));
+  }
+  void test_isSubtypeOf_self() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    InterfaceType typeA = elementA.type;
+    JUnitTestCase.assertTrue(typeA.isSubtypeOf(typeA));
+  }
+  void test_isSubtypeOf_typeArguments() {
+    ClassElement elementA = ElementFactory.classElement2("A", ["E"]);
+    ClassElement elementI = ElementFactory.classElement2("I", []);
+    ClassElement elementJ = ElementFactory.classElement("J", elementI.type, []);
+    ClassElement elementK = ElementFactory.classElement2("K", []);
+    InterfaceType typeA = elementA.type;
+    InterfaceTypeImpl typeAI = new InterfaceTypeImpl.con1(elementA);
+    InterfaceTypeImpl typeAJ = new InterfaceTypeImpl.con1(elementA);
+    InterfaceTypeImpl typeAK = new InterfaceTypeImpl.con1(elementA);
+    typeAI.typeArguments = <Type2> [elementI.type];
+    typeAJ.typeArguments = <Type2> [elementJ.type];
+    typeAK.typeArguments = <Type2> [elementK.type];
+    JUnitTestCase.assertTrue(typeAJ.isSubtypeOf(typeAI));
+    JUnitTestCase.assertFalse(typeAI.isSubtypeOf(typeAJ));
+    JUnitTestCase.assertTrue(typeAI.isSubtypeOf(typeAI));
+    JUnitTestCase.assertTrue(typeA.isSubtypeOf(typeAI));
+    JUnitTestCase.assertTrue(typeA.isSubtypeOf(typeAJ));
+    JUnitTestCase.assertTrue(typeAI.isSubtypeOf(typeA));
+    JUnitTestCase.assertTrue(typeAJ.isSubtypeOf(typeA));
+    JUnitTestCase.assertFalse(typeAI.isSubtypeOf(typeAK));
+    JUnitTestCase.assertFalse(typeAK.isSubtypeOf(typeAI));
+  }
+  void test_isSupertypeOf_directSupertype() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeB = elementB.type;
+    JUnitTestCase.assertFalse(typeB.isSupertypeOf(typeA));
+    JUnitTestCase.assertTrue(typeA.isSupertypeOf(typeB));
+  }
+  void test_isSupertypeOf_dynamic() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    InterfaceType typeA = elementA.type;
+    Type2 dynamicType = DynamicTypeImpl.instance;
+    JUnitTestCase.assertTrue(dynamicType.isSupertypeOf(typeA));
+    JUnitTestCase.assertFalse(typeA.isSupertypeOf(dynamicType));
+  }
+  void test_isSupertypeOf_indirectSupertype() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
+    ClassElement elementC = ElementFactory.classElement("C", elementB.type, []);
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeC = elementC.type;
+    JUnitTestCase.assertFalse(typeC.isSupertypeOf(typeA));
+    JUnitTestCase.assertTrue(typeA.isSupertypeOf(typeC));
+  }
+  void test_isSupertypeOf_interface() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
+    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    InterfaceType typeObject = elementA.supertype;
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeB = elementB.type;
+    InterfaceType typeC = elementC.type;
+    elementC.interfaces = <InterfaceType> [typeB];
+    JUnitTestCase.assertTrue(typeB.isSupertypeOf(typeC));
+    JUnitTestCase.assertTrue(typeObject.isSupertypeOf(typeC));
+    JUnitTestCase.assertTrue(typeA.isSupertypeOf(typeC));
+    JUnitTestCase.assertFalse(typeC.isSupertypeOf(typeA));
+  }
+  void test_isSupertypeOf_mixins() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
+    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    InterfaceType typeObject = elementA.supertype;
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeB = elementB.type;
+    InterfaceType typeC = elementC.type;
+    elementC.mixins = <InterfaceType> [typeB];
+    JUnitTestCase.assertTrue(typeB.isSupertypeOf(typeC));
+    JUnitTestCase.assertTrue(typeObject.isSupertypeOf(typeC));
+    JUnitTestCase.assertFalse(typeA.isSupertypeOf(typeC));
+    JUnitTestCase.assertFalse(typeC.isSupertypeOf(typeA));
+  }
+  void test_isSupertypeOf_object() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeObject = elementA.supertype;
+    JUnitTestCase.assertFalse(typeA.isSupertypeOf(typeObject));
+    JUnitTestCase.assertTrue(typeObject.isSupertypeOf(typeA));
+  }
+  void test_isSupertypeOf_self() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    InterfaceType typeA = elementA.type;
+    JUnitTestCase.assertTrue(typeA.isSupertypeOf(typeA));
+  }
+  void test_setTypeArguments() {
+    InterfaceTypeImpl type22 = (ElementFactory.classElement2("A", []).type as InterfaceTypeImpl);
+    List<Type2> typeArguments = <Type2> [new InterfaceTypeImpl.con1(ElementFactory.classElement2("B", [])), new InterfaceTypeImpl.con1(ElementFactory.classElement2("C", []))];
+    type22.typeArguments = typeArguments;
+    JUnitTestCase.assertEquals(typeArguments, type22.typeArguments);
+  }
+  void test_substitute_equal() {
+    ClassElementImpl classElement = new ClassElementImpl(ASTFactory.identifier2("A"));
+    TypeVariableElementImpl parameterElement = new TypeVariableElementImpl(ASTFactory.identifier2("E"));
+    InterfaceTypeImpl type = new InterfaceTypeImpl.con1(classElement);
+    TypeVariableTypeImpl parameter = new TypeVariableTypeImpl(parameterElement);
+    type.typeArguments = <Type2> [parameter];
+    InterfaceTypeImpl argumentType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("B")));
+    InterfaceType result = type.substitute2(<Type2> [argumentType], <Type2> [parameter]);
+    JUnitTestCase.assertEquals(classElement, result.element);
+    List<Type2> resultArguments = result.typeArguments;
+    EngineTestCase.assertLength(1, resultArguments);
+    JUnitTestCase.assertEquals(argumentType, resultArguments[0]);
+  }
+  void test_substitute_notEqual() {
+    ClassElementImpl classElement = new ClassElementImpl(ASTFactory.identifier2("A"));
+    TypeVariableElementImpl parameterElement = new TypeVariableElementImpl(ASTFactory.identifier2("E"));
+    InterfaceTypeImpl type = new InterfaceTypeImpl.con1(classElement);
+    TypeVariableTypeImpl parameter = new TypeVariableTypeImpl(parameterElement);
+    type.typeArguments = <Type2> [parameter];
+    InterfaceTypeImpl argumentType = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("B")));
+    TypeVariableTypeImpl parameterType = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier2("F")));
+    InterfaceType result = type.substitute2(<Type2> [argumentType], <Type2> [parameterType]);
+    JUnitTestCase.assertEquals(classElement, result.element);
+    List<Type2> resultArguments = result.typeArguments;
+    EngineTestCase.assertLength(1, resultArguments);
+    JUnitTestCase.assertEquals(parameter, resultArguments[0]);
+  }
+  static dartSuite() {
+    _ut.group('InterfaceTypeImplTest', () {
+      _ut.test('test_computeLongestInheritancePathToObject_multipleInterfacePaths', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_computeLongestInheritancePathToObject_multipleInterfacePaths);
+      });
+      _ut.test('test_computeLongestInheritancePathToObject_multipleSuperclassPaths', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_computeLongestInheritancePathToObject_multipleSuperclassPaths);
+      });
+      _ut.test('test_computeLongestInheritancePathToObject_object', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_computeLongestInheritancePathToObject_object);
+      });
+      _ut.test('test_computeLongestInheritancePathToObject_singleInterfacePath', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_computeLongestInheritancePathToObject_singleInterfacePath);
+      });
+      _ut.test('test_computeLongestInheritancePathToObject_singleSuperclassPath', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_computeLongestInheritancePathToObject_singleSuperclassPath);
+      });
+      _ut.test('test_computeSuperinterfaceSet_multipleInterfacePaths', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_computeSuperinterfaceSet_multipleInterfacePaths);
+      });
+      _ut.test('test_computeSuperinterfaceSet_multipleSuperclassPaths', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_computeSuperinterfaceSet_multipleSuperclassPaths);
+      });
+      _ut.test('test_computeSuperinterfaceSet_singleInterfacePath', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_computeSuperinterfaceSet_singleInterfacePath);
+      });
+      _ut.test('test_computeSuperinterfaceSet_singleSuperclassPath', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_computeSuperinterfaceSet_singleSuperclassPath);
+      });
+      _ut.test('test_creation', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_creation);
+      });
+      _ut.test('test_getElement', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_getElement);
+      });
+      _ut.test('test_getLeastUpperBound_directInterfaceCase', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_getLeastUpperBound_directInterfaceCase);
+      });
+      _ut.test('test_getLeastUpperBound_directSubclassCase', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_getLeastUpperBound_directSubclassCase);
+      });
+      _ut.test('test_getLeastUpperBound_functionType', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_getLeastUpperBound_functionType);
+      });
+      _ut.test('test_getLeastUpperBound_mixinCase', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_getLeastUpperBound_mixinCase);
+      });
+      _ut.test('test_getLeastUpperBound_null', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_getLeastUpperBound_null);
+      });
+      _ut.test('test_getLeastUpperBound_object', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_getLeastUpperBound_object);
+      });
+      _ut.test('test_getLeastUpperBound_self', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_getLeastUpperBound_self);
+      });
+      _ut.test('test_getLeastUpperBound_sharedSuperclass1', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_getLeastUpperBound_sharedSuperclass1);
+      });
+      _ut.test('test_getLeastUpperBound_sharedSuperclass2', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_getLeastUpperBound_sharedSuperclass2);
+      });
+      _ut.test('test_getLeastUpperBound_sharedSuperclass3', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_getLeastUpperBound_sharedSuperclass3);
+      });
+      _ut.test('test_getLeastUpperBound_sharedSuperclass4', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_getLeastUpperBound_sharedSuperclass4);
+      });
+      _ut.test('test_getLeastUpperBound_sharedSuperinterface1', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_getLeastUpperBound_sharedSuperinterface1);
+      });
+      _ut.test('test_getLeastUpperBound_sharedSuperinterface2', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_getLeastUpperBound_sharedSuperinterface2);
+      });
+      _ut.test('test_getLeastUpperBound_sharedSuperinterface3', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_getLeastUpperBound_sharedSuperinterface3);
+      });
+      _ut.test('test_getLeastUpperBound_sharedSuperinterface4', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_getLeastUpperBound_sharedSuperinterface4);
+      });
+      _ut.test('test_getTypeArguments', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_getTypeArguments);
+      });
+      _ut.test('test_isDirectSupertypeOf_extends', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isDirectSupertypeOf_extends);
+      });
+      _ut.test('test_isDirectSupertypeOf_false', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isDirectSupertypeOf_false);
+      });
+      _ut.test('test_isDirectSupertypeOf_implements', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isDirectSupertypeOf_implements);
+      });
+      _ut.test('test_isDirectSupertypeOf_with', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isDirectSupertypeOf_with);
+      });
+      _ut.test('test_isMoreSpecificThan_bottom', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isMoreSpecificThan_bottom);
+      });
+      _ut.test('test_isMoreSpecificThan_covariance', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isMoreSpecificThan_covariance);
+      });
+      _ut.test('test_isMoreSpecificThan_directSupertype', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isMoreSpecificThan_directSupertype);
+      });
+      _ut.test('test_isMoreSpecificThan_dynamic', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isMoreSpecificThan_dynamic);
+      });
+      _ut.test('test_isMoreSpecificThan_indirectSupertype', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isMoreSpecificThan_indirectSupertype);
+      });
+      _ut.test('test_isMoreSpecificThan_self', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isMoreSpecificThan_self);
+      });
+      _ut.test('test_isSubtypeOf_directSubtype', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_directSubtype);
+      });
+      _ut.test('test_isSubtypeOf_dynamic', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_dynamic);
+      });
+      _ut.test('test_isSubtypeOf_indirectSubtype', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_indirectSubtype);
+      });
+      _ut.test('test_isSubtypeOf_interface', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_interface);
+      });
+      _ut.test('test_isSubtypeOf_mixins', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_mixins);
+      });
+      _ut.test('test_isSubtypeOf_object', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_object);
+      });
+      _ut.test('test_isSubtypeOf_self', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_self);
+      });
+      _ut.test('test_isSubtypeOf_typeArguments', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isSubtypeOf_typeArguments);
+      });
+      _ut.test('test_isSupertypeOf_directSupertype', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isSupertypeOf_directSupertype);
+      });
+      _ut.test('test_isSupertypeOf_dynamic', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isSupertypeOf_dynamic);
+      });
+      _ut.test('test_isSupertypeOf_indirectSupertype', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isSupertypeOf_indirectSupertype);
+      });
+      _ut.test('test_isSupertypeOf_interface', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isSupertypeOf_interface);
+      });
+      _ut.test('test_isSupertypeOf_mixins', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isSupertypeOf_mixins);
+      });
+      _ut.test('test_isSupertypeOf_object', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isSupertypeOf_object);
+      });
+      _ut.test('test_isSupertypeOf_self', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_isSupertypeOf_self);
+      });
+      _ut.test('test_setTypeArguments', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_setTypeArguments);
+      });
+      _ut.test('test_substitute_equal', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_substitute_equal);
+      });
+      _ut.test('test_substitute_notEqual', () {
+        final __test = new InterfaceTypeImplTest();
+        runJUnitTest(__test, __test.test_substitute_notEqual);
+      });
+    });
+  }
+}
+class ClassElementImplTest extends EngineTestCase {
+  void test_allSupertypes_interface() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
+    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    InterfaceType typeObject = elementA.supertype;
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeB = elementB.type;
+    InterfaceType typeC = elementC.type;
+    elementC.interfaces = <InterfaceType> [typeB];
+    List<InterfaceType> supers = elementC.allSupertypes;
+    List<InterfaceType> types = new List<InterfaceType>();
+    types.addAll(supers);
+    JUnitTestCase.assertTrue(types.contains(typeA));
+    JUnitTestCase.assertTrue(types.contains(typeB));
+    JUnitTestCase.assertTrue(types.contains(typeObject));
+    JUnitTestCase.assertFalse(types.contains(typeC));
+  }
+  void test_allSupertypes_mixins() {
+    ClassElement elementA = ElementFactory.classElement2("A", []);
+    ClassElement elementB = ElementFactory.classElement("B", elementA.type, []);
+    ClassElementImpl elementC = (ElementFactory.classElement2("C", []) as ClassElementImpl);
+    InterfaceType typeObject = elementA.supertype;
+    InterfaceType typeA = elementA.type;
+    InterfaceType typeB = elementB.type;
+    InterfaceType typeC = elementC.type;
+    elementC.mixins = <InterfaceType> [typeB];
+    List<InterfaceType> supers = elementC.allSupertypes;
+    List<InterfaceType> types = new List<InterfaceType>();
+    types.addAll(supers);
+    JUnitTestCase.assertFalse(types.contains(typeA));
+    JUnitTestCase.assertTrue(types.contains(typeB));
+    JUnitTestCase.assertTrue(types.contains(typeObject));
+    JUnitTestCase.assertFalse(types.contains(typeC));
+  }
+  void test_lookUpGetter_declared() {
+    LibraryElementImpl library6 = ElementFactory.library(new AnalysisContextImpl(), "lib");
+    ClassElementImpl classA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    String getterName = "g";
+    PropertyAccessorElement getter = ElementFactory.getterElement(getterName, false, null);
+    classA.accessors = <PropertyAccessorElement> [getter];
+    ((library6.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classA];
+    JUnitTestCase.assertSame(getter, classA.lookUpGetter(getterName, library6));
+  }
+  void test_lookUpGetter_inherited() {
+    LibraryElementImpl library7 = ElementFactory.library(new AnalysisContextImpl(), "lib");
+    ClassElementImpl classA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    String getterName = "g";
+    PropertyAccessorElement getter = ElementFactory.getterElement(getterName, false, null);
+    classA.accessors = <PropertyAccessorElement> [getter];
+    ClassElementImpl classB = (ElementFactory.classElement("B", classA.type, []) as ClassElementImpl);
+    ((library7.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classA, classB];
+    JUnitTestCase.assertSame(getter, classB.lookUpGetter(getterName, library7));
+  }
+  void test_lookUpGetter_undeclared() {
+    LibraryElementImpl library8 = ElementFactory.library(new AnalysisContextImpl(), "lib");
+    ClassElementImpl classA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ((library8.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classA];
+    JUnitTestCase.assertNull(classA.lookUpGetter("g", library8));
+  }
+  void test_lookUpMethod_declared() {
+    LibraryElementImpl library9 = ElementFactory.library(new AnalysisContextImpl(), "lib");
+    ClassElementImpl classA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    String methodName = "m";
+    MethodElement method = ElementFactory.methodElement(methodName, null, []);
+    classA.methods = <MethodElement> [method];
+    ((library9.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classA];
+    JUnitTestCase.assertSame(method, classA.lookUpMethod(methodName, library9));
+  }
+  void test_lookUpMethod_inherited() {
+    LibraryElementImpl library10 = ElementFactory.library(new AnalysisContextImpl(), "lib");
+    ClassElementImpl classA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    String methodName = "m";
+    MethodElement method = ElementFactory.methodElement(methodName, null, []);
+    classA.methods = <MethodElement> [method];
+    ClassElementImpl classB = (ElementFactory.classElement("B", classA.type, []) as ClassElementImpl);
+    ((library10.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classA, classB];
+    JUnitTestCase.assertSame(method, classB.lookUpMethod(methodName, library10));
+  }
+  void test_lookUpMethod_undeclared() {
+    LibraryElementImpl library11 = ElementFactory.library(new AnalysisContextImpl(), "lib");
+    ClassElementImpl classA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ((library11.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classA];
+    JUnitTestCase.assertNull(classA.lookUpMethod("m", library11));
+  }
+  void test_lookUpSetter_declared() {
+    LibraryElementImpl library12 = ElementFactory.library(new AnalysisContextImpl(), "lib");
+    ClassElementImpl classA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    String setterName = "s";
+    PropertyAccessorElement setter = ElementFactory.setterElement(setterName, false, null);
+    classA.accessors = <PropertyAccessorElement> [setter];
+    ((library12.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classA];
+    JUnitTestCase.assertSame(setter, classA.lookUpSetter(setterName, library12));
+  }
+  void test_lookUpSetter_inherited() {
+    LibraryElementImpl library13 = ElementFactory.library(new AnalysisContextImpl(), "lib");
+    ClassElementImpl classA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    String setterName = "s";
+    PropertyAccessorElement setter = ElementFactory.setterElement(setterName, false, null);
+    classA.accessors = <PropertyAccessorElement> [setter];
+    ClassElementImpl classB = (ElementFactory.classElement("B", classA.type, []) as ClassElementImpl);
+    ((library13.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classA, classB];
+    JUnitTestCase.assertSame(setter, classB.lookUpSetter(setterName, library13));
+  }
+  void test_lookUpSetter_undeclared() {
+    LibraryElementImpl library14 = ElementFactory.library(new AnalysisContextImpl(), "lib");
+    ClassElementImpl classA = (ElementFactory.classElement2("A", []) as ClassElementImpl);
+    ((library14.definingCompilationUnit as CompilationUnitElementImpl)).types = <ClassElement> [classA];
+    JUnitTestCase.assertNull(classA.lookUpSetter("s", library14));
+  }
+  static dartSuite() {
+    _ut.group('ClassElementImplTest', () {
+      _ut.test('test_allSupertypes_interface', () {
+        final __test = new ClassElementImplTest();
+        runJUnitTest(__test, __test.test_allSupertypes_interface);
+      });
+      _ut.test('test_allSupertypes_mixins', () {
+        final __test = new ClassElementImplTest();
+        runJUnitTest(__test, __test.test_allSupertypes_mixins);
+      });
+      _ut.test('test_lookUpGetter_declared', () {
+        final __test = new ClassElementImplTest();
+        runJUnitTest(__test, __test.test_lookUpGetter_declared);
+      });
+      _ut.test('test_lookUpGetter_inherited', () {
+        final __test = new ClassElementImplTest();
+        runJUnitTest(__test, __test.test_lookUpGetter_inherited);
+      });
+      _ut.test('test_lookUpGetter_undeclared', () {
+        final __test = new ClassElementImplTest();
+        runJUnitTest(__test, __test.test_lookUpGetter_undeclared);
+      });
+      _ut.test('test_lookUpMethod_declared', () {
+        final __test = new ClassElementImplTest();
+        runJUnitTest(__test, __test.test_lookUpMethod_declared);
+      });
+      _ut.test('test_lookUpMethod_inherited', () {
+        final __test = new ClassElementImplTest();
+        runJUnitTest(__test, __test.test_lookUpMethod_inherited);
+      });
+      _ut.test('test_lookUpMethod_undeclared', () {
+        final __test = new ClassElementImplTest();
+        runJUnitTest(__test, __test.test_lookUpMethod_undeclared);
+      });
+      _ut.test('test_lookUpSetter_declared', () {
+        final __test = new ClassElementImplTest();
+        runJUnitTest(__test, __test.test_lookUpSetter_declared);
+      });
+      _ut.test('test_lookUpSetter_inherited', () {
+        final __test = new ClassElementImplTest();
+        runJUnitTest(__test, __test.test_lookUpSetter_inherited);
+      });
+      _ut.test('test_lookUpSetter_undeclared', () {
+        final __test = new ClassElementImplTest();
+        runJUnitTest(__test, __test.test_lookUpSetter_undeclared);
+      });
+    });
+  }
+}
+class TypeVariableTypeImplTest extends EngineTestCase {
+  void test_creation() {
+    JUnitTestCase.assertNotNull(new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier2("E"))));
+  }
+  void test_getElement() {
+    TypeVariableElementImpl element = new TypeVariableElementImpl(ASTFactory.identifier2("E"));
+    TypeVariableTypeImpl type = new TypeVariableTypeImpl(element);
+    JUnitTestCase.assertEquals(element, type.element);
+  }
+  void test_substitute_equal() {
+    TypeVariableElementImpl element = new TypeVariableElementImpl(ASTFactory.identifier2("E"));
+    TypeVariableTypeImpl type = new TypeVariableTypeImpl(element);
+    InterfaceTypeImpl argument = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("A")));
+    TypeVariableTypeImpl parameter = new TypeVariableTypeImpl(element);
+    JUnitTestCase.assertSame(argument, type.substitute2(<Type2> [argument], <Type2> [parameter]));
+  }
+  void test_substitute_notEqual() {
+    TypeVariableTypeImpl type = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier2("E")));
+    InterfaceTypeImpl argument = new InterfaceTypeImpl.con1(new ClassElementImpl(ASTFactory.identifier2("A")));
+    TypeVariableTypeImpl parameter = new TypeVariableTypeImpl(new TypeVariableElementImpl(ASTFactory.identifier2("F")));
+    JUnitTestCase.assertSame(type, type.substitute2(<Type2> [argument], <Type2> [parameter]));
+  }
+  static dartSuite() {
+    _ut.group('TypeVariableTypeImplTest', () {
+      _ut.test('test_creation', () {
+        final __test = new TypeVariableTypeImplTest();
+        runJUnitTest(__test, __test.test_creation);
+      });
+      _ut.test('test_getElement', () {
+        final __test = new TypeVariableTypeImplTest();
+        runJUnitTest(__test, __test.test_getElement);
+      });
+      _ut.test('test_substitute_equal', () {
+        final __test = new TypeVariableTypeImplTest();
+        runJUnitTest(__test, __test.test_substitute_equal);
+      });
+      _ut.test('test_substitute_notEqual', () {
+        final __test = new TypeVariableTypeImplTest();
+        runJUnitTest(__test, __test.test_substitute_notEqual);
+      });
+    });
+  }
+}
+main() {
+  ClassElementImplTest.dartSuite();
+  ElementLocationImplTest.dartSuite();
+  ElementImplTest.dartSuite();
+  LibraryElementImplTest.dartSuite();
+  FunctionTypeImplTest.dartSuite();
+  InterfaceTypeImplTest.dartSuite();
+  TypeVariableTypeImplTest.dartSuite();
+}
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/test/generated/parser_test.dart b/pkg/analyzer-experimental/test/generated/parser_test.dart
index efeded0..b8ba2d3 100644
--- a/pkg/analyzer-experimental/test/generated/parser_test.dart
+++ b/pkg/analyzer-experimental/test/generated/parser_test.dart
@@ -35,7 +35,7 @@
    * @throws Exception if the method could not be invoked or throws an exception
    * @throws AssertionFailedError if the result is {@code null} or if any errors are produced
    */
-  static Object parse(String methodName, List<Object> objects, String source) => parse2(methodName, objects, source, new List<AnalysisError>.fixedLength(0));
+  static Object parse(String methodName, List<Object> objects, String source) => parse3(methodName, objects, source, new List<AnalysisError>.fixedLength(0));
   /**
    * Invoke a parse method in {@link Parser}. The method is assumed to have the given number and
    * type of parameters and will be invoked with the given arguments.
@@ -51,7 +51,7 @@
    * @throws AssertionFailedError if the result is {@code null} or the errors produced while
    * scanning and parsing the source do not match the expected errors
    */
-  static Object parse2(String methodName, List<Object> objects, String source, List<AnalysisError> errors) {
+  static Object parse3(String methodName, List<Object> objects, String source, List<AnalysisError> errors) {
     GatheringErrorListener listener = new GatheringErrorListener();
     Object result = invokeParserMethod(methodName, objects, source, listener);
     listener.assertErrors(errors);
@@ -72,7 +72,7 @@
    * @throws AssertionFailedError if the result is {@code null} or the errors produced while
    * scanning and parsing the source do not match the expected errors
    */
-  static Object parse3(String methodName, List<Object> objects, String source, List<ErrorCode> errorCodes) {
+  static Object parse4(String methodName, List<Object> objects, String source, List<ErrorCode> errorCodes) {
     GatheringErrorListener listener = new GatheringErrorListener();
     Object result = invokeParserMethod(methodName, objects, source, listener);
     listener.assertErrors2(errorCodes);
@@ -91,7 +91,7 @@
    * @throws AssertionFailedError if the result is {@code null} or the errors produced while
    * scanning and parsing the source do not match the expected errors
    */
-  static Object parse4(String methodName, String source, List<ErrorCode> errorCodes) => parse3(methodName, ParserTestCase._EMPTY_ARGUMENTS, source, errorCodes);
+  static Object parse5(String methodName, String source, List<ErrorCode> errorCodes) => parse4(methodName, _EMPTY_ARGUMENTS, source, errorCodes);
   /**
    * Parse the given source as a compilation unit.
    * @param source the source to be parsed
@@ -128,7 +128,7 @@
     Expression expression = parser.parseExpression(token);
     JUnitTestCase.assertNotNull(expression);
     listener.assertErrors2(errorCodes);
-    return expression as Expression;
+    return (expression as Expression);
   }
   /**
    * Parse the given source as a statement.
@@ -147,7 +147,7 @@
     Statement statement = parser.parseStatement(token);
     JUnitTestCase.assertNotNull(statement);
     listener.assertErrors2(errorCodes);
-    return statement as Statement;
+    return (statement as Statement);
   }
   /**
    * Parse the given source as a sequence of statements.
@@ -192,7 +192,7 @@
     Parser parser = new Parser(null, listener);
     Object result = invokeParserMethodImpl(parser, methodName, objects, tokenStream);
     JUnitTestCase.assertNotNull(result);
-    return result as Object;
+    return (result as Object);
   }
   /**
    * Invoke a method in {@link Parser}. The method is assumed to have no arguments.
@@ -207,7 +207,7 @@
    * @throws AssertionFailedError if the result is {@code null} or the errors produced while
    * scanning and parsing the source do not match the expected errors
    */
-  static Object invokeParserMethod2(String methodName, String source, GatheringErrorListener listener) => invokeParserMethod(methodName, ParserTestCase._EMPTY_ARGUMENTS, source, listener);
+  static Object invokeParserMethod2(String methodName, String source, GatheringErrorListener listener) => invokeParserMethod(methodName, _EMPTY_ARGUMENTS, source, listener);
   /**
    * Return a CommentAndMetadata object with the given values that can be used for testing.
    * @param comment the comment to be wrapped in the object
@@ -264,13 +264,13 @@
    * @param node the AST node being validated
    */
   void validate(ASTNode node) {
-    ASTNode parent12 = node.parent;
+    ASTNode parent11 = node.parent;
     if (node is CompilationUnit) {
-      if (parent12 != null) {
+      if (parent11 != null) {
         _errors.add("Compilation units should not have a parent");
       }
     } else {
-      if (parent12 == null) {
+      if (parent11 == null) {
         _errors.add("No parent for ${node.runtimeType.toString()}");
       }
     }
@@ -285,15 +285,15 @@
     if (nodeStart < 0 || nodeLength < 0) {
       _errors.add("No source info for ${node.runtimeType.toString()}");
     }
-    if (parent12 != null) {
+    if (parent11 != null) {
       int nodeEnd = nodeStart + nodeLength;
-      int parentStart = parent12.offset;
-      int parentEnd = parentStart + parent12.length;
+      int parentStart = parent11.offset;
+      int parentEnd = parentStart + parent11.length;
       if (nodeStart < parentStart) {
-        _errors.add("Invalid source start (${nodeStart}) for ${node.runtimeType.toString()} inside ${parent12.runtimeType.toString()} (${parentStart})");
+        _errors.add("Invalid source start (${nodeStart}) for ${node.runtimeType.toString()} inside ${parent11.runtimeType.toString()} (${parentStart})");
       }
       if (nodeEnd > parentEnd) {
-        _errors.add("Invalid source end (${nodeEnd}) for ${node.runtimeType.toString()} inside ${parent12.runtimeType.toString()} (${parentStart})");
+        _errors.add("Invalid source end (${nodeEnd}) for ${node.runtimeType.toString()} inside ${parent11.runtimeType.toString()} (${parentStart})");
       }
     }
   }
@@ -349,13 +349,13 @@
   }
   void test_assignmentExpression_missing_compound2() {
     AssignmentExpression expression = ParserTestCase.parseExpression("x = = 0", []);
-    Expression syntheticExpression = (expression.rightHandSide as AssignmentExpression).leftHandSide;
+    Expression syntheticExpression = ((expression.rightHandSide as AssignmentExpression)).leftHandSide;
     EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
     JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
   }
   void test_assignmentExpression_missing_compound3() {
     AssignmentExpression expression = ParserTestCase.parseExpression("x = y =", []);
-    Expression syntheticExpression = (expression.rightHandSide as AssignmentExpression).rightHandSide;
+    Expression syntheticExpression = ((expression.rightHandSide as AssignmentExpression)).rightHandSide;
     EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
     JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
   }
@@ -472,12 +472,12 @@
     EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
   }
   void test_conditionalExpression_missingElse() {
-    ConditionalExpression expression = ParserTestCase.parse4("parseConditionalExpression", "x ? y :", []);
+    ConditionalExpression expression = ParserTestCase.parse5("parseConditionalExpression", "x ? y :", []);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.elseExpression);
     JUnitTestCase.assertTrue(expression.elseExpression.isSynthetic());
   }
   void test_conditionalExpression_missingThen() {
-    ConditionalExpression expression = ParserTestCase.parse4("parseConditionalExpression", "x ? : z", []);
+    ConditionalExpression expression = ParserTestCase.parse5("parseConditionalExpression", "x ? : z", []);
     EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.thenExpression);
     JUnitTestCase.assertTrue(expression.thenExpression.isSynthetic());
   }
@@ -516,21 +516,21 @@
     EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
   }
   void test_expressionList_multiple_end() {
-    List<Expression> result = ParserTestCase.parse4("parseExpressionList", ", 2, 3, 4", []);
+    List<Expression> result = ParserTestCase.parse5("parseExpressionList", ", 2, 3, 4", []);
     EngineTestCase.assertSize(4, result);
     Expression syntheticExpression = result[0];
     EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
     JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
   }
   void test_expressionList_multiple_middle() {
-    List<Expression> result = ParserTestCase.parse4("parseExpressionList", "1, 2, , 4", []);
+    List<Expression> result = ParserTestCase.parse5("parseExpressionList", "1, 2, , 4", []);
     EngineTestCase.assertSize(4, result);
     Expression syntheticExpression = result[2];
     EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
     JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
   }
   void test_expressionList_multiple_start() {
-    List<Expression> result = ParserTestCase.parse4("parseExpressionList", "1, 2, 3,", []);
+    List<Expression> result = ParserTestCase.parse5("parseExpressionList", "1, 2, 3,", []);
     EngineTestCase.assertSize(4, result);
     Expression syntheticExpression = result[3];
     EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
@@ -685,7 +685,7 @@
     CompilationUnit unit = ParserTestCase.parseCompilationUnit("external void f(A a);", [ParserErrorCode.UNEXPECTED_TOKEN]);
     NodeList<CompilationUnitMember> declarations3 = unit.declarations;
     EngineTestCase.assertSize(1, declarations3);
-    FunctionDeclaration declaration = declarations3[0] as FunctionDeclaration;
+    FunctionDeclaration declaration = (declarations3[0] as FunctionDeclaration);
     JUnitTestCase.assertNotNull(declaration);
   }
   static dartSuite() {
@@ -1007,10 +1007,10 @@
 class SimpleParserTest extends ParserTestCase {
   void fail_parseCommentReference_this() {
     CommentReference reference = ParserTestCase.parse("parseCommentReference", <Object> ["this", 5], "");
-    SimpleIdentifier identifier8 = EngineTestCase.assertInstanceOf(SimpleIdentifier, reference.identifier);
-    JUnitTestCase.assertNotNull(identifier8.token);
-    JUnitTestCase.assertEquals("a", identifier8.name);
-    JUnitTestCase.assertEquals(5, identifier8.offset);
+    SimpleIdentifier identifier13 = EngineTestCase.assertInstanceOf(SimpleIdentifier, reference.identifier);
+    JUnitTestCase.assertNotNull(identifier13.token);
+    JUnitTestCase.assertEquals("a", identifier13.name);
+    JUnitTestCase.assertEquals(5, identifier13.offset);
   }
   void test_computeStringValue_emptyInterpolationPrefix() {
     JUnitTestCase.assertEquals("", computeStringValue("'''"));
@@ -1180,21 +1180,21 @@
     JUnitTestCase.assertFalse(isSwitchMember("break;"));
   }
   void test_parseAdditiveExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parse4("parseAdditiveExpression", "x + y", []);
+    BinaryExpression expression = ParserTestCase.parse5("parseAdditiveExpression", "x + y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.PLUS, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseAdditiveExpression_super() {
-    BinaryExpression expression = ParserTestCase.parse4("parseAdditiveExpression", "super + y", []);
+    BinaryExpression expression = ParserTestCase.parse5("parseAdditiveExpression", "super + y", []);
     EngineTestCase.assertInstanceOf(SuperExpression, expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.PLUS, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseAnnotation_n1() {
-    Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A", []);
+    Annotation annotation = ParserTestCase.parse5("parseAnnotation", "@A", []);
     JUnitTestCase.assertNotNull(annotation.atSign);
     JUnitTestCase.assertNotNull(annotation.name);
     JUnitTestCase.assertNull(annotation.period);
@@ -1202,7 +1202,7 @@
     JUnitTestCase.assertNull(annotation.arguments);
   }
   void test_parseAnnotation_n1_a() {
-    Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A(x,y)", []);
+    Annotation annotation = ParserTestCase.parse5("parseAnnotation", "@A(x,y)", []);
     JUnitTestCase.assertNotNull(annotation.atSign);
     JUnitTestCase.assertNotNull(annotation.name);
     JUnitTestCase.assertNull(annotation.period);
@@ -1210,7 +1210,7 @@
     JUnitTestCase.assertNotNull(annotation.arguments);
   }
   void test_parseAnnotation_n2() {
-    Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A.B", []);
+    Annotation annotation = ParserTestCase.parse5("parseAnnotation", "@A.B", []);
     JUnitTestCase.assertNotNull(annotation.atSign);
     JUnitTestCase.assertNotNull(annotation.name);
     JUnitTestCase.assertNull(annotation.period);
@@ -1218,7 +1218,7 @@
     JUnitTestCase.assertNull(annotation.arguments);
   }
   void test_parseAnnotation_n2_a() {
-    Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A.B(x,y)", []);
+    Annotation annotation = ParserTestCase.parse5("parseAnnotation", "@A.B(x,y)", []);
     JUnitTestCase.assertNotNull(annotation.atSign);
     JUnitTestCase.assertNotNull(annotation.name);
     JUnitTestCase.assertNull(annotation.period);
@@ -1226,7 +1226,7 @@
     JUnitTestCase.assertNotNull(annotation.arguments);
   }
   void test_parseAnnotation_n3() {
-    Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A.B.C", []);
+    Annotation annotation = ParserTestCase.parse5("parseAnnotation", "@A.B.C", []);
     JUnitTestCase.assertNotNull(annotation.atSign);
     JUnitTestCase.assertNotNull(annotation.name);
     JUnitTestCase.assertNotNull(annotation.period);
@@ -1234,7 +1234,7 @@
     JUnitTestCase.assertNull(annotation.arguments);
   }
   void test_parseAnnotation_n3_a() {
-    Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A.B.C(x,y)", []);
+    Annotation annotation = ParserTestCase.parse5("parseAnnotation", "@A.B.C(x,y)", []);
     JUnitTestCase.assertNotNull(annotation.atSign);
     JUnitTestCase.assertNotNull(annotation.name);
     JUnitTestCase.assertNotNull(annotation.period);
@@ -1242,45 +1242,45 @@
     JUnitTestCase.assertNotNull(annotation.arguments);
   }
   void test_parseArgument_named() {
-    NamedExpression expression = ParserTestCase.parse4("parseArgument", "n: x", []);
-    Label name18 = expression.name;
-    JUnitTestCase.assertNotNull(name18);
-    JUnitTestCase.assertNotNull(name18.label);
-    JUnitTestCase.assertNotNull(name18.colon);
+    NamedExpression expression = ParserTestCase.parse5("parseArgument", "n: x", []);
+    Label name20 = expression.name;
+    JUnitTestCase.assertNotNull(name20);
+    JUnitTestCase.assertNotNull(name20.label);
+    JUnitTestCase.assertNotNull(name20.colon);
     JUnitTestCase.assertNotNull(expression.expression);
   }
   void test_parseArgument_unnamed() {
     String lexeme = "x";
-    SimpleIdentifier identifier = ParserTestCase.parse4("parseArgument", lexeme, []);
+    SimpleIdentifier identifier = ParserTestCase.parse5("parseArgument", lexeme, []);
     JUnitTestCase.assertEquals(lexeme, identifier.name);
   }
   void test_parseArgumentDefinitionTest() {
-    ArgumentDefinitionTest test = ParserTestCase.parse4("parseArgumentDefinitionTest", "?x", []);
+    ArgumentDefinitionTest test = ParserTestCase.parse5("parseArgumentDefinitionTest", "?x", []);
     JUnitTestCase.assertNotNull(test.question);
     JUnitTestCase.assertNotNull(test.identifier);
   }
   void test_parseArgumentList_empty() {
-    ArgumentList argumentList = ParserTestCase.parse4("parseArgumentList", "()", []);
-    NodeList<Expression> arguments6 = argumentList.arguments;
-    EngineTestCase.assertSize(0, arguments6);
+    ArgumentList argumentList = ParserTestCase.parse5("parseArgumentList", "()", []);
+    NodeList<Expression> arguments7 = argumentList.arguments;
+    EngineTestCase.assertSize(0, arguments7);
   }
   void test_parseArgumentList_mixed() {
-    ArgumentList argumentList = ParserTestCase.parse4("parseArgumentList", "(w, x, y: y, z: z)", []);
-    NodeList<Expression> arguments7 = argumentList.arguments;
-    EngineTestCase.assertSize(4, arguments7);
+    ArgumentList argumentList = ParserTestCase.parse5("parseArgumentList", "(w, x, y: y, z: z)", []);
+    NodeList<Expression> arguments8 = argumentList.arguments;
+    EngineTestCase.assertSize(4, arguments8);
   }
   void test_parseArgumentList_noNamed() {
-    ArgumentList argumentList = ParserTestCase.parse4("parseArgumentList", "(x, y, z)", []);
-    NodeList<Expression> arguments8 = argumentList.arguments;
-    EngineTestCase.assertSize(3, arguments8);
+    ArgumentList argumentList = ParserTestCase.parse5("parseArgumentList", "(x, y, z)", []);
+    NodeList<Expression> arguments9 = argumentList.arguments;
+    EngineTestCase.assertSize(3, arguments9);
   }
   void test_parseArgumentList_onlyNamed() {
-    ArgumentList argumentList = ParserTestCase.parse4("parseArgumentList", "(x: x, y: y)", []);
-    NodeList<Expression> arguments9 = argumentList.arguments;
-    EngineTestCase.assertSize(2, arguments9);
+    ArgumentList argumentList = ParserTestCase.parse5("parseArgumentList", "(x: x, y: y)", []);
+    NodeList<Expression> arguments10 = argumentList.arguments;
+    EngineTestCase.assertSize(2, arguments10);
   }
   void test_parseAssertStatement() {
-    AssertStatement statement = ParserTestCase.parse4("parseAssertStatement", "assert (x);", []);
+    AssertStatement statement = ParserTestCase.parse5("parseAssertStatement", "assert (x);", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.condition);
@@ -1289,11 +1289,11 @@
   }
   void test_parseAssignableExpression_expression_args_dot() {
     PropertyAccess propertyAccess = ParserTestCase.parse("parseAssignableExpression", <Object> [false], "(x)(y).z");
-    FunctionExpressionInvocation invocation = propertyAccess.target as FunctionExpressionInvocation;
+    FunctionExpressionInvocation invocation = (propertyAccess.target as FunctionExpressionInvocation);
     JUnitTestCase.assertNotNull(invocation.function);
-    ArgumentList argumentList10 = invocation.argumentList;
-    JUnitTestCase.assertNotNull(argumentList10);
-    EngineTestCase.assertSize(1, argumentList10.arguments);
+    ArgumentList argumentList13 = invocation.argumentList;
+    JUnitTestCase.assertNotNull(argumentList13);
+    EngineTestCase.assertSize(1, argumentList13.arguments);
     JUnitTestCase.assertNotNull(propertyAccess.operator);
     JUnitTestCase.assertNotNull(propertyAccess.propertyName);
   }
@@ -1316,11 +1316,11 @@
   }
   void test_parseAssignableExpression_identifier_args_dot() {
     PropertyAccess propertyAccess = ParserTestCase.parse("parseAssignableExpression", <Object> [false], "x(y).z");
-    MethodInvocation invocation = propertyAccess.target as MethodInvocation;
+    MethodInvocation invocation = (propertyAccess.target as MethodInvocation);
     JUnitTestCase.assertEquals("x", invocation.methodName.name);
-    ArgumentList argumentList11 = invocation.argumentList;
-    JUnitTestCase.assertNotNull(argumentList11);
-    EngineTestCase.assertSize(1, argumentList11.arguments);
+    ArgumentList argumentList14 = invocation.argumentList;
+    JUnitTestCase.assertNotNull(argumentList14);
+    EngineTestCase.assertSize(1, argumentList14.arguments);
     JUnitTestCase.assertNotNull(propertyAccess.operator);
     JUnitTestCase.assertNotNull(propertyAccess.propertyName);
   }
@@ -1362,107 +1362,107 @@
     JUnitTestCase.assertNotNull(selector.rightBracket);
   }
   void test_parseAssignableSelector_none() {
-    SimpleIdentifier selector = ParserTestCase.parse("parseAssignableSelector", <Object> [new SimpleIdentifier(null), true], ";");
+    SimpleIdentifier selector = ParserTestCase.parse("parseAssignableSelector", <Object> [new SimpleIdentifier.full(null), true], ";");
     JUnitTestCase.assertNotNull(selector);
   }
   void test_parseBitwiseAndExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parse4("parseBitwiseAndExpression", "x & y", []);
+    BinaryExpression expression = ParserTestCase.parse5("parseBitwiseAndExpression", "x & y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.AMPERSAND, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseBitwiseAndExpression_super() {
-    BinaryExpression expression = ParserTestCase.parse4("parseBitwiseAndExpression", "super & y", []);
+    BinaryExpression expression = ParserTestCase.parse5("parseBitwiseAndExpression", "super & y", []);
     EngineTestCase.assertInstanceOf(SuperExpression, expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.AMPERSAND, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseBitwiseOrExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parse4("parseBitwiseOrExpression", "x | y", []);
+    BinaryExpression expression = ParserTestCase.parse5("parseBitwiseOrExpression", "x | y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.BAR, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseBitwiseOrExpression_super() {
-    BinaryExpression expression = ParserTestCase.parse4("parseBitwiseOrExpression", "super | y", []);
+    BinaryExpression expression = ParserTestCase.parse5("parseBitwiseOrExpression", "super | y", []);
     EngineTestCase.assertInstanceOf(SuperExpression, expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.BAR, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseBitwiseXorExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parse4("parseBitwiseXorExpression", "x ^ y", []);
+    BinaryExpression expression = ParserTestCase.parse5("parseBitwiseXorExpression", "x ^ y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.CARET, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseBitwiseXorExpression_super() {
-    BinaryExpression expression = ParserTestCase.parse4("parseBitwiseXorExpression", "super ^ y", []);
+    BinaryExpression expression = ParserTestCase.parse5("parseBitwiseXorExpression", "super ^ y", []);
     EngineTestCase.assertInstanceOf(SuperExpression, expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.CARET, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseBlock_empty() {
-    Block block = ParserTestCase.parse4("parseBlock", "{}", []);
+    Block block = ParserTestCase.parse5("parseBlock", "{}", []);
     JUnitTestCase.assertNotNull(block.leftBracket);
     EngineTestCase.assertSize(0, block.statements);
     JUnitTestCase.assertNotNull(block.rightBracket);
   }
   void test_parseBlock_nonEmpty() {
-    Block block = ParserTestCase.parse4("parseBlock", "{;}", []);
+    Block block = ParserTestCase.parse5("parseBlock", "{;}", []);
     JUnitTestCase.assertNotNull(block.leftBracket);
     EngineTestCase.assertSize(1, block.statements);
     JUnitTestCase.assertNotNull(block.rightBracket);
   }
   void test_parseBreakStatement_label() {
-    BreakStatement statement = ParserTestCase.parse4("parseBreakStatement", "break foo;", []);
+    BreakStatement statement = ParserTestCase.parse5("parseBreakStatement", "break foo;", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.label);
     JUnitTestCase.assertNotNull(statement.semicolon);
   }
   void test_parseBreakStatement_noLabel() {
-    BreakStatement statement = ParserTestCase.parse4("parseBreakStatement", "break;", [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]);
+    BreakStatement statement = ParserTestCase.parse5("parseBreakStatement", "break;", [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNull(statement.label);
     JUnitTestCase.assertNotNull(statement.semicolon);
   }
   void test_parseCascadeSection_i() {
-    IndexExpression section = ParserTestCase.parse4("parseCascadeSection", "..[i]", []);
+    IndexExpression section = ParserTestCase.parse5("parseCascadeSection", "..[i]", []);
     JUnitTestCase.assertNull(section.array);
     JUnitTestCase.assertNotNull(section.leftBracket);
     JUnitTestCase.assertNotNull(section.index);
     JUnitTestCase.assertNotNull(section.rightBracket);
   }
   void test_parseCascadeSection_ia() {
-    FunctionExpressionInvocation section = ParserTestCase.parse4("parseCascadeSection", "..[i](b)", []);
+    FunctionExpressionInvocation section = ParserTestCase.parse5("parseCascadeSection", "..[i](b)", []);
     EngineTestCase.assertInstanceOf(IndexExpression, section.function);
     JUnitTestCase.assertNotNull(section.argumentList);
   }
   void test_parseCascadeSection_p() {
-    PropertyAccess section = ParserTestCase.parse4("parseCascadeSection", "..a", []);
+    PropertyAccess section = ParserTestCase.parse5("parseCascadeSection", "..a", []);
     JUnitTestCase.assertNull(section.target);
     JUnitTestCase.assertNotNull(section.operator);
     JUnitTestCase.assertNotNull(section.propertyName);
   }
   void test_parseCascadeSection_p_assign() {
-    AssignmentExpression section = ParserTestCase.parse4("parseCascadeSection", "..a = 3", []);
+    AssignmentExpression section = ParserTestCase.parse5("parseCascadeSection", "..a = 3", []);
     JUnitTestCase.assertNotNull(section.leftHandSide);
     JUnitTestCase.assertNotNull(section.operator);
     JUnitTestCase.assertNotNull(section.rightHandSide);
   }
   void test_parseCascadeSection_p_builtIn() {
-    PropertyAccess section = ParserTestCase.parse4("parseCascadeSection", "..as", []);
+    PropertyAccess section = ParserTestCase.parse5("parseCascadeSection", "..as", []);
     JUnitTestCase.assertNull(section.target);
     JUnitTestCase.assertNotNull(section.operator);
     JUnitTestCase.assertNotNull(section.propertyName);
   }
   void test_parseCascadeSection_pa() {
-    MethodInvocation section = ParserTestCase.parse4("parseCascadeSection", "..a(b)", []);
+    MethodInvocation section = ParserTestCase.parse5("parseCascadeSection", "..a(b)", []);
     JUnitTestCase.assertNull(section.target);
     JUnitTestCase.assertNotNull(section.period);
     JUnitTestCase.assertNotNull(section.methodName);
@@ -1470,19 +1470,19 @@
     EngineTestCase.assertSize(1, section.argumentList.arguments);
   }
   void test_parseCascadeSection_paa() {
-    FunctionExpressionInvocation section = ParserTestCase.parse4("parseCascadeSection", "..a(b)(c)", []);
+    FunctionExpressionInvocation section = ParserTestCase.parse5("parseCascadeSection", "..a(b)(c)", []);
     EngineTestCase.assertInstanceOf(MethodInvocation, section.function);
     JUnitTestCase.assertNotNull(section.argumentList);
     EngineTestCase.assertSize(1, section.argumentList.arguments);
   }
   void test_parseCascadeSection_paapaa() {
-    FunctionExpressionInvocation section = ParserTestCase.parse4("parseCascadeSection", "..a(b)(c).d(e)(f)", []);
+    FunctionExpressionInvocation section = ParserTestCase.parse5("parseCascadeSection", "..a(b)(c).d(e)(f)", []);
     EngineTestCase.assertInstanceOf(FunctionExpressionInvocation, section.function);
     JUnitTestCase.assertNotNull(section.argumentList);
     EngineTestCase.assertSize(1, section.argumentList.arguments);
   }
   void test_parseCascadeSection_pap() {
-    PropertyAccess section = ParserTestCase.parse4("parseCascadeSection", "..a(b).c", []);
+    PropertyAccess section = ParserTestCase.parse5("parseCascadeSection", "..a(b).c", []);
     JUnitTestCase.assertNotNull(section.target);
     JUnitTestCase.assertNotNull(section.operator);
     JUnitTestCase.assertNotNull(section.propertyName);
@@ -1627,9 +1627,9 @@
     JUnitTestCase.assertNull(field.keyword);
     VariableDeclarationList list = field.fields;
     JUnitTestCase.assertNotNull(list);
-    NodeList<VariableDeclaration> variables6 = list.variables;
-    EngineTestCase.assertSize(1, variables6);
-    VariableDeclaration variable = variables6[0];
+    NodeList<VariableDeclaration> variables4 = list.variables;
+    EngineTestCase.assertSize(1, variables4);
+    VariableDeclaration variable = variables4[0];
     JUnitTestCase.assertNotNull(variable.name);
   }
   void test_parseClassMember_field_namedGet() {
@@ -1639,9 +1639,9 @@
     JUnitTestCase.assertNull(field.keyword);
     VariableDeclarationList list = field.fields;
     JUnitTestCase.assertNotNull(list);
-    NodeList<VariableDeclaration> variables7 = list.variables;
-    EngineTestCase.assertSize(1, variables7);
-    VariableDeclaration variable = variables7[0];
+    NodeList<VariableDeclaration> variables5 = list.variables;
+    EngineTestCase.assertSize(1, variables5);
+    VariableDeclaration variable = variables5[0];
     JUnitTestCase.assertNotNull(variable.name);
   }
   void test_parseClassMember_field_namedOperator() {
@@ -1651,9 +1651,9 @@
     JUnitTestCase.assertNull(field.keyword);
     VariableDeclarationList list = field.fields;
     JUnitTestCase.assertNotNull(list);
-    NodeList<VariableDeclaration> variables8 = list.variables;
-    EngineTestCase.assertSize(1, variables8);
-    VariableDeclaration variable = variables8[0];
+    NodeList<VariableDeclaration> variables6 = list.variables;
+    EngineTestCase.assertSize(1, variables6);
+    VariableDeclaration variable = variables6[0];
     JUnitTestCase.assertNotNull(variable.name);
   }
   void test_parseClassMember_field_namedSet() {
@@ -1663,9 +1663,9 @@
     JUnitTestCase.assertNull(field.keyword);
     VariableDeclarationList list = field.fields;
     JUnitTestCase.assertNotNull(list);
-    NodeList<VariableDeclaration> variables9 = list.variables;
-    EngineTestCase.assertSize(1, variables9);
-    VariableDeclaration variable = variables9[0];
+    NodeList<VariableDeclaration> variables7 = list.variables;
+    EngineTestCase.assertSize(1, variables7);
+    VariableDeclaration variable = variables7[0];
     JUnitTestCase.assertNotNull(variable.name);
   }
   void test_parseClassMember_getter_void() {
@@ -1876,121 +1876,121 @@
     JUnitTestCase.assertNotNull(constructor.body);
   }
   void test_parseCombinators_h() {
-    List<Combinator> combinators = ParserTestCase.parse4("parseCombinators", "hide a;", []);
+    List<Combinator> combinators = ParserTestCase.parse5("parseCombinators", "hide a;", []);
     EngineTestCase.assertSize(1, combinators);
-    HideCombinator combinator = combinators[0] as HideCombinator;
+    HideCombinator combinator = (combinators[0] as HideCombinator);
     JUnitTestCase.assertNotNull(combinator);
     JUnitTestCase.assertNotNull(combinator.keyword);
     EngineTestCase.assertSize(1, combinator.hiddenNames);
   }
   void test_parseCombinators_hs() {
-    List<Combinator> combinators = ParserTestCase.parse4("parseCombinators", "hide a show b;", []);
+    List<Combinator> combinators = ParserTestCase.parse5("parseCombinators", "hide a show b;", []);
     EngineTestCase.assertSize(2, combinators);
-    HideCombinator hideCombinator = combinators[0] as HideCombinator;
+    HideCombinator hideCombinator = (combinators[0] as HideCombinator);
     JUnitTestCase.assertNotNull(hideCombinator);
     JUnitTestCase.assertNotNull(hideCombinator.keyword);
     EngineTestCase.assertSize(1, hideCombinator.hiddenNames);
-    ShowCombinator showCombinator = combinators[1] as ShowCombinator;
+    ShowCombinator showCombinator = (combinators[1] as ShowCombinator);
     JUnitTestCase.assertNotNull(showCombinator);
     JUnitTestCase.assertNotNull(showCombinator.keyword);
     EngineTestCase.assertSize(1, showCombinator.shownNames);
   }
   void test_parseCombinators_hshs() {
-    List<Combinator> combinators = ParserTestCase.parse4("parseCombinators", "hide a show b hide c show d;", []);
+    List<Combinator> combinators = ParserTestCase.parse5("parseCombinators", "hide a show b hide c show d;", []);
     EngineTestCase.assertSize(4, combinators);
   }
   void test_parseCombinators_s() {
-    List<Combinator> combinators = ParserTestCase.parse4("parseCombinators", "show a;", []);
+    List<Combinator> combinators = ParserTestCase.parse5("parseCombinators", "show a;", []);
     EngineTestCase.assertSize(1, combinators);
-    ShowCombinator combinator = combinators[0] as ShowCombinator;
+    ShowCombinator combinator = (combinators[0] as ShowCombinator);
     JUnitTestCase.assertNotNull(combinator);
     JUnitTestCase.assertNotNull(combinator.keyword);
     EngineTestCase.assertSize(1, combinator.shownNames);
   }
   void test_parseCommentAndMetadata_c() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("parseCommentAndMetadata", "/** 1 */ void", []);
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "/** 1 */ void", []);
     JUnitTestCase.assertNotNull(commentAndMetadata.comment);
     EngineTestCase.assertSize(0, commentAndMetadata.metadata);
   }
   void test_parseCommentAndMetadata_cmc() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("parseCommentAndMetadata", "/** 1 */ @A /** 2 */ void", []);
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "/** 1 */ @A /** 2 */ void", []);
     JUnitTestCase.assertNotNull(commentAndMetadata.comment);
     EngineTestCase.assertSize(1, commentAndMetadata.metadata);
   }
   void test_parseCommentAndMetadata_cmcm() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("parseCommentAndMetadata", "/** 1 */ @A /** 2 */ @B void", []);
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "/** 1 */ @A /** 2 */ @B void", []);
     JUnitTestCase.assertNotNull(commentAndMetadata.comment);
     EngineTestCase.assertSize(2, commentAndMetadata.metadata);
   }
   void test_parseCommentAndMetadata_cmm() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("parseCommentAndMetadata", "/** 1 */ @A @B void", []);
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "/** 1 */ @A @B void", []);
     JUnitTestCase.assertNotNull(commentAndMetadata.comment);
     EngineTestCase.assertSize(2, commentAndMetadata.metadata);
   }
   void test_parseCommentAndMetadata_m() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("parseCommentAndMetadata", "@A void", []);
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "@A void", []);
     JUnitTestCase.assertNull(commentAndMetadata.comment);
     EngineTestCase.assertSize(1, commentAndMetadata.metadata);
   }
   void test_parseCommentAndMetadata_mcm() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("parseCommentAndMetadata", "@A /** 1 */ @B void", []);
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "@A /** 1 */ @B void", []);
     JUnitTestCase.assertNotNull(commentAndMetadata.comment);
     EngineTestCase.assertSize(2, commentAndMetadata.metadata);
   }
   void test_parseCommentAndMetadata_mcmc() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("parseCommentAndMetadata", "@A /** 1 */ @B /** 2 */ void", []);
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "@A /** 1 */ @B /** 2 */ void", []);
     JUnitTestCase.assertNotNull(commentAndMetadata.comment);
     EngineTestCase.assertSize(2, commentAndMetadata.metadata);
   }
   void test_parseCommentAndMetadata_mm() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("parseCommentAndMetadata", "@A @B(x) void", []);
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "@A @B(x) void", []);
     JUnitTestCase.assertNull(commentAndMetadata.comment);
     EngineTestCase.assertSize(2, commentAndMetadata.metadata);
   }
   void test_parseCommentAndMetadata_none() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("parseCommentAndMetadata", "void", []);
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse5("parseCommentAndMetadata", "void", []);
     JUnitTestCase.assertNull(commentAndMetadata.comment);
     EngineTestCase.assertSize(0, commentAndMetadata.metadata);
   }
   void test_parseCommentReference_new_prefixed() {
     CommentReference reference = ParserTestCase.parse("parseCommentReference", <Object> ["new a.b", 7], "");
     PrefixedIdentifier prefixedIdentifier = EngineTestCase.assertInstanceOf(PrefixedIdentifier, reference.identifier);
-    SimpleIdentifier prefix9 = prefixedIdentifier.prefix;
-    JUnitTestCase.assertNotNull(prefix9.token);
-    JUnitTestCase.assertEquals("a", prefix9.name);
-    JUnitTestCase.assertEquals(11, prefix9.offset);
+    SimpleIdentifier prefix10 = prefixedIdentifier.prefix;
+    JUnitTestCase.assertNotNull(prefix10.token);
+    JUnitTestCase.assertEquals("a", prefix10.name);
+    JUnitTestCase.assertEquals(11, prefix10.offset);
     JUnitTestCase.assertNotNull(prefixedIdentifier.period);
-    SimpleIdentifier identifier9 = prefixedIdentifier.identifier;
-    JUnitTestCase.assertNotNull(identifier9.token);
-    JUnitTestCase.assertEquals("b", identifier9.name);
-    JUnitTestCase.assertEquals(13, identifier9.offset);
+    SimpleIdentifier identifier14 = prefixedIdentifier.identifier;
+    JUnitTestCase.assertNotNull(identifier14.token);
+    JUnitTestCase.assertEquals("b", identifier14.name);
+    JUnitTestCase.assertEquals(13, identifier14.offset);
   }
   void test_parseCommentReference_new_simple() {
     CommentReference reference = ParserTestCase.parse("parseCommentReference", <Object> ["new a", 5], "");
-    SimpleIdentifier identifier10 = EngineTestCase.assertInstanceOf(SimpleIdentifier, reference.identifier);
-    JUnitTestCase.assertNotNull(identifier10.token);
-    JUnitTestCase.assertEquals("a", identifier10.name);
-    JUnitTestCase.assertEquals(9, identifier10.offset);
+    SimpleIdentifier identifier15 = EngineTestCase.assertInstanceOf(SimpleIdentifier, reference.identifier);
+    JUnitTestCase.assertNotNull(identifier15.token);
+    JUnitTestCase.assertEquals("a", identifier15.name);
+    JUnitTestCase.assertEquals(9, identifier15.offset);
   }
   void test_parseCommentReference_prefixed() {
     CommentReference reference = ParserTestCase.parse("parseCommentReference", <Object> ["a.b", 7], "");
     PrefixedIdentifier prefixedIdentifier = EngineTestCase.assertInstanceOf(PrefixedIdentifier, reference.identifier);
-    SimpleIdentifier prefix10 = prefixedIdentifier.prefix;
-    JUnitTestCase.assertNotNull(prefix10.token);
-    JUnitTestCase.assertEquals("a", prefix10.name);
-    JUnitTestCase.assertEquals(7, prefix10.offset);
+    SimpleIdentifier prefix11 = prefixedIdentifier.prefix;
+    JUnitTestCase.assertNotNull(prefix11.token);
+    JUnitTestCase.assertEquals("a", prefix11.name);
+    JUnitTestCase.assertEquals(7, prefix11.offset);
     JUnitTestCase.assertNotNull(prefixedIdentifier.period);
-    SimpleIdentifier identifier11 = prefixedIdentifier.identifier;
-    JUnitTestCase.assertNotNull(identifier11.token);
-    JUnitTestCase.assertEquals("b", identifier11.name);
-    JUnitTestCase.assertEquals(9, identifier11.offset);
+    SimpleIdentifier identifier16 = prefixedIdentifier.identifier;
+    JUnitTestCase.assertNotNull(identifier16.token);
+    JUnitTestCase.assertEquals("b", identifier16.name);
+    JUnitTestCase.assertEquals(9, identifier16.offset);
   }
   void test_parseCommentReference_simple() {
     CommentReference reference = ParserTestCase.parse("parseCommentReference", <Object> ["a", 5], "");
-    SimpleIdentifier identifier12 = EngineTestCase.assertInstanceOf(SimpleIdentifier, reference.identifier);
-    JUnitTestCase.assertNotNull(identifier12.token);
-    JUnitTestCase.assertEquals("a", identifier12.name);
-    JUnitTestCase.assertEquals(5, identifier12.offset);
+    SimpleIdentifier identifier17 = EngineTestCase.assertInstanceOf(SimpleIdentifier, reference.identifier);
+    JUnitTestCase.assertNotNull(identifier17.token);
+    JUnitTestCase.assertEquals("a", identifier17.name);
+    JUnitTestCase.assertEquals(5, identifier17.offset);
   }
   void test_parseCommentReferences_multiLine() {
     List<Token> tokens = <Token> [new StringToken(TokenType.MULTI_LINE_COMMENT, "/** xxx [a] yyy [b] zzz */", 3)];
@@ -2023,31 +2023,31 @@
     JUnitTestCase.assertEquals(35, reference.offset);
   }
   void test_parseCompilationUnit_directives_multiple() {
-    CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "library l;\npart 'a.dart';", []);
+    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "library l;\npart 'a.dart';", []);
     JUnitTestCase.assertNull(unit.scriptTag);
     EngineTestCase.assertSize(2, unit.directives);
     EngineTestCase.assertSize(0, unit.declarations);
   }
   void test_parseCompilationUnit_directives_single() {
-    CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "library l;", []);
+    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "library l;", []);
     JUnitTestCase.assertNull(unit.scriptTag);
     EngineTestCase.assertSize(1, unit.directives);
     EngineTestCase.assertSize(0, unit.declarations);
   }
   void test_parseCompilationUnit_empty() {
-    CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "", []);
+    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "", []);
     JUnitTestCase.assertNull(unit.scriptTag);
     EngineTestCase.assertSize(0, unit.directives);
     EngineTestCase.assertSize(0, unit.declarations);
   }
   void test_parseCompilationUnit_script() {
-    CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "#! /bin/dart", []);
+    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "#! /bin/dart", []);
     JUnitTestCase.assertNotNull(unit.scriptTag);
     EngineTestCase.assertSize(0, unit.directives);
     EngineTestCase.assertSize(0, unit.declarations);
   }
   void test_parseCompilationUnit_topLevelDeclaration() {
-    CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "class A {}", []);
+    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "class A {}", []);
     JUnitTestCase.assertNull(unit.scriptTag);
     EngineTestCase.assertSize(0, unit.directives);
     EngineTestCase.assertSize(1, unit.declarations);
@@ -2192,7 +2192,7 @@
     JUnitTestCase.assertNotNull(declaration.variables);
   }
   void test_parseConditionalExpression() {
-    ConditionalExpression expression = ParserTestCase.parse4("parseConditionalExpression", "x ? y : z", []);
+    ConditionalExpression expression = ParserTestCase.parse5("parseConditionalExpression", "x ? y : z", []);
     JUnitTestCase.assertNotNull(expression.condition);
     JUnitTestCase.assertNotNull(expression.question);
     JUnitTestCase.assertNotNull(expression.thenExpression);
@@ -2200,7 +2200,7 @@
     JUnitTestCase.assertNotNull(expression.elseExpression);
   }
   void test_parseConstExpression_instanceCreation() {
-    InstanceCreationExpression expression = ParserTestCase.parse4("parseConstExpression", "const A()", []);
+    InstanceCreationExpression expression = ParserTestCase.parse5("parseConstExpression", "const A()", []);
     JUnitTestCase.assertNotNull(expression.keyword);
     ConstructorName name = expression.constructorName;
     JUnitTestCase.assertNotNull(name);
@@ -2210,7 +2210,7 @@
     JUnitTestCase.assertNotNull(expression.argumentList);
   }
   void test_parseConstExpression_listLiteral_typed() {
-    ListLiteral literal = ParserTestCase.parse4("parseConstExpression", "const <A> []", []);
+    ListLiteral literal = ParserTestCase.parse5("parseConstExpression", "const <A> []", []);
     JUnitTestCase.assertNotNull(literal.modifier);
     JUnitTestCase.assertNotNull(literal.typeArguments);
     JUnitTestCase.assertNotNull(literal.leftBracket);
@@ -2218,7 +2218,7 @@
     JUnitTestCase.assertNotNull(literal.rightBracket);
   }
   void test_parseConstExpression_listLiteral_untyped() {
-    ListLiteral literal = ParserTestCase.parse4("parseConstExpression", "const []", []);
+    ListLiteral literal = ParserTestCase.parse5("parseConstExpression", "const []", []);
     JUnitTestCase.assertNotNull(literal.modifier);
     JUnitTestCase.assertNull(literal.typeArguments);
     JUnitTestCase.assertNotNull(literal.leftBracket);
@@ -2226,14 +2226,14 @@
     JUnitTestCase.assertNotNull(literal.rightBracket);
   }
   void test_parseConstExpression_mapLiteral_typed() {
-    MapLiteral literal = ParserTestCase.parse4("parseConstExpression", "const <A> {}", []);
+    MapLiteral literal = ParserTestCase.parse5("parseConstExpression", "const <A> {}", []);
     JUnitTestCase.assertNotNull(literal.leftBracket);
     EngineTestCase.assertSize(0, literal.entries);
     JUnitTestCase.assertNotNull(literal.rightBracket);
     JUnitTestCase.assertNotNull(literal.typeArguments);
   }
   void test_parseConstExpression_mapLiteral_untyped() {
-    MapLiteral literal = ParserTestCase.parse4("parseConstExpression", "const {}", []);
+    MapLiteral literal = ParserTestCase.parse5("parseConstExpression", "const {}", []);
     JUnitTestCase.assertNotNull(literal.leftBracket);
     EngineTestCase.assertSize(0, literal.entries);
     JUnitTestCase.assertNotNull(literal.rightBracket);
@@ -2242,7 +2242,7 @@
   void test_parseConstructor() {
   }
   void test_parseConstructorFieldInitializer_qualified() {
-    ConstructorFieldInitializer invocation = ParserTestCase.parse4("parseConstructorFieldInitializer", "this.a = b", []);
+    ConstructorFieldInitializer invocation = ParserTestCase.parse5("parseConstructorFieldInitializer", "this.a = b", []);
     JUnitTestCase.assertNotNull(invocation.equals);
     JUnitTestCase.assertNotNull(invocation.expression);
     JUnitTestCase.assertNotNull(invocation.fieldName);
@@ -2250,7 +2250,7 @@
     JUnitTestCase.assertNotNull(invocation.period);
   }
   void test_parseConstructorFieldInitializer_unqualified() {
-    ConstructorFieldInitializer invocation = ParserTestCase.parse4("parseConstructorFieldInitializer", "a = b", []);
+    ConstructorFieldInitializer invocation = ParserTestCase.parse5("parseConstructorFieldInitializer", "a = b", []);
     JUnitTestCase.assertNotNull(invocation.equals);
     JUnitTestCase.assertNotNull(invocation.expression);
     JUnitTestCase.assertNotNull(invocation.fieldName);
@@ -2258,37 +2258,37 @@
     JUnitTestCase.assertNull(invocation.period);
   }
   void test_parseConstructorName_named_noPrefix() {
-    ConstructorName name = ParserTestCase.parse4("parseConstructorName", "A.n;", []);
+    ConstructorName name = ParserTestCase.parse5("parseConstructorName", "A.n;", []);
     JUnitTestCase.assertNotNull(name.type);
     JUnitTestCase.assertNull(name.period);
     JUnitTestCase.assertNull(name.name);
   }
   void test_parseConstructorName_named_prefixed() {
-    ConstructorName name = ParserTestCase.parse4("parseConstructorName", "p.A.n;", []);
+    ConstructorName name = ParserTestCase.parse5("parseConstructorName", "p.A.n;", []);
     JUnitTestCase.assertNotNull(name.type);
     JUnitTestCase.assertNotNull(name.period);
     JUnitTestCase.assertNotNull(name.name);
   }
   void test_parseConstructorName_unnamed_noPrefix() {
-    ConstructorName name = ParserTestCase.parse4("parseConstructorName", "A;", []);
+    ConstructorName name = ParserTestCase.parse5("parseConstructorName", "A;", []);
     JUnitTestCase.assertNotNull(name.type);
     JUnitTestCase.assertNull(name.period);
     JUnitTestCase.assertNull(name.name);
   }
   void test_parseConstructorName_unnamed_prefixed() {
-    ConstructorName name = ParserTestCase.parse4("parseConstructorName", "p.A;", []);
+    ConstructorName name = ParserTestCase.parse5("parseConstructorName", "p.A;", []);
     JUnitTestCase.assertNotNull(name.type);
     JUnitTestCase.assertNull(name.period);
     JUnitTestCase.assertNull(name.name);
   }
   void test_parseContinueStatement_label() {
-    ContinueStatement statement = ParserTestCase.parse4("parseContinueStatement", "continue foo;", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
+    ContinueStatement statement = ParserTestCase.parse5("parseContinueStatement", "continue foo;", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.label);
     JUnitTestCase.assertNotNull(statement.semicolon);
   }
   void test_parseContinueStatement_noLabel() {
-    ContinueStatement statement = ParserTestCase.parse4("parseContinueStatement", "continue;", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
+    ContinueStatement statement = ParserTestCase.parse5("parseContinueStatement", "continue;", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNull(statement.label);
     JUnitTestCase.assertNotNull(statement.semicolon);
@@ -2296,14 +2296,14 @@
   void test_parseDirective_export() {
     ExportDirective directive = ParserTestCase.parse("parseDirective", <Object> [emptyCommentAndMetadata()], "export 'lib/lib.dart';");
     JUnitTestCase.assertNotNull(directive.keyword);
-    JUnitTestCase.assertNotNull(directive.libraryUri);
+    JUnitTestCase.assertNotNull(directive.uri);
     EngineTestCase.assertSize(0, directive.combinators);
     JUnitTestCase.assertNotNull(directive.semicolon);
   }
   void test_parseDirective_import() {
     ImportDirective directive = ParserTestCase.parse("parseDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart';");
     JUnitTestCase.assertNotNull(directive.keyword);
-    JUnitTestCase.assertNotNull(directive.libraryUri);
+    JUnitTestCase.assertNotNull(directive.uri);
     JUnitTestCase.assertNull(directive.asToken);
     JUnitTestCase.assertNull(directive.prefix);
     EngineTestCase.assertSize(0, directive.combinators);
@@ -2318,7 +2318,7 @@
   void test_parseDirective_part() {
     PartDirective directive = ParserTestCase.parse("parseDirective", <Object> [emptyCommentAndMetadata()], "part 'lib/lib.dart';");
     JUnitTestCase.assertNotNull(directive.partToken);
-    JUnitTestCase.assertNotNull(directive.partUri);
+    JUnitTestCase.assertNotNull(directive.uri);
     JUnitTestCase.assertNotNull(directive.semicolon);
   }
   void test_parseDirective_partOf() {
@@ -2329,13 +2329,13 @@
     JUnitTestCase.assertNotNull(directive.semicolon);
   }
   void test_parseDocumentationComment_block() {
-    Comment comment = ParserTestCase.parse4("parseDocumentationComment", "/** */ class", []);
+    Comment comment = ParserTestCase.parse5("parseDocumentationComment", "/** */ class", []);
     JUnitTestCase.assertFalse(comment.isBlock());
     JUnitTestCase.assertTrue(comment.isDocumentation());
     JUnitTestCase.assertFalse(comment.isEndOfLine());
   }
   void test_parseDocumentationComment_block_withReference() {
-    Comment comment = ParserTestCase.parse4("parseDocumentationComment", "/** [a] */ class", []);
+    Comment comment = ParserTestCase.parse5("parseDocumentationComment", "/** [a] */ class", []);
     JUnitTestCase.assertFalse(comment.isBlock());
     JUnitTestCase.assertTrue(comment.isDocumentation());
     JUnitTestCase.assertFalse(comment.isEndOfLine());
@@ -2346,13 +2346,13 @@
     JUnitTestCase.assertEquals(5, reference.offset);
   }
   void test_parseDocumentationComment_endOfLine() {
-    Comment comment = ParserTestCase.parse4("parseDocumentationComment", "/// \n/// \n class", []);
+    Comment comment = ParserTestCase.parse5("parseDocumentationComment", "/// \n/// \n class", []);
     JUnitTestCase.assertFalse(comment.isBlock());
     JUnitTestCase.assertTrue(comment.isDocumentation());
     JUnitTestCase.assertFalse(comment.isEndOfLine());
   }
   void test_parseDoStatement() {
-    DoStatement statement = ParserTestCase.parse4("parseDoStatement", "do {} while (x);", []);
+    DoStatement statement = ParserTestCase.parse5("parseDoStatement", "do {} while (x);", []);
     JUnitTestCase.assertNotNull(statement.doKeyword);
     JUnitTestCase.assertNotNull(statement.body);
     JUnitTestCase.assertNotNull(statement.whileKeyword);
@@ -2362,18 +2362,18 @@
     JUnitTestCase.assertNotNull(statement.semicolon);
   }
   void test_parseEmptyStatement() {
-    EmptyStatement statement = ParserTestCase.parse4("parseEmptyStatement", ";", []);
+    EmptyStatement statement = ParserTestCase.parse5("parseEmptyStatement", ";", []);
     JUnitTestCase.assertNotNull(statement.semicolon);
   }
   void test_parseEqualityExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parse4("parseEqualityExpression", "x == y", []);
+    BinaryExpression expression = ParserTestCase.parse5("parseEqualityExpression", "x == y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.EQ_EQ, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseEqualityExpression_super() {
-    BinaryExpression expression = ParserTestCase.parse4("parseEqualityExpression", "super == y", []);
+    BinaryExpression expression = ParserTestCase.parse5("parseEqualityExpression", "super == y", []);
     EngineTestCase.assertInstanceOf(SuperExpression, expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.EQ_EQ, expression.operator.type);
@@ -2382,56 +2382,56 @@
   void test_parseExportDirective_hide() {
     ExportDirective directive = ParserTestCase.parse("parseExportDirective", <Object> [emptyCommentAndMetadata()], "export 'lib/lib.dart' hide A, B;");
     JUnitTestCase.assertNotNull(directive.keyword);
-    JUnitTestCase.assertNotNull(directive.libraryUri);
+    JUnitTestCase.assertNotNull(directive.uri);
     EngineTestCase.assertSize(1, directive.combinators);
     JUnitTestCase.assertNotNull(directive.semicolon);
   }
   void test_parseExportDirective_hide_show() {
     ExportDirective directive = ParserTestCase.parse("parseExportDirective", <Object> [emptyCommentAndMetadata()], "export 'lib/lib.dart' hide A show B;");
     JUnitTestCase.assertNotNull(directive.keyword);
-    JUnitTestCase.assertNotNull(directive.libraryUri);
+    JUnitTestCase.assertNotNull(directive.uri);
     EngineTestCase.assertSize(2, directive.combinators);
     JUnitTestCase.assertNotNull(directive.semicolon);
   }
   void test_parseExportDirective_noCombinator() {
     ExportDirective directive = ParserTestCase.parse("parseExportDirective", <Object> [emptyCommentAndMetadata()], "export 'lib/lib.dart';");
     JUnitTestCase.assertNotNull(directive.keyword);
-    JUnitTestCase.assertNotNull(directive.libraryUri);
+    JUnitTestCase.assertNotNull(directive.uri);
     EngineTestCase.assertSize(0, directive.combinators);
     JUnitTestCase.assertNotNull(directive.semicolon);
   }
   void test_parseExportDirective_show() {
     ExportDirective directive = ParserTestCase.parse("parseExportDirective", <Object> [emptyCommentAndMetadata()], "export 'lib/lib.dart' show A, B;");
     JUnitTestCase.assertNotNull(directive.keyword);
-    JUnitTestCase.assertNotNull(directive.libraryUri);
+    JUnitTestCase.assertNotNull(directive.uri);
     EngineTestCase.assertSize(1, directive.combinators);
     JUnitTestCase.assertNotNull(directive.semicolon);
   }
   void test_parseExportDirective_show_hide() {
     ExportDirective directive = ParserTestCase.parse("parseExportDirective", <Object> [emptyCommentAndMetadata()], "export 'lib/lib.dart' show B hide A;");
     JUnitTestCase.assertNotNull(directive.keyword);
-    JUnitTestCase.assertNotNull(directive.libraryUri);
+    JUnitTestCase.assertNotNull(directive.uri);
     EngineTestCase.assertSize(2, directive.combinators);
     JUnitTestCase.assertNotNull(directive.semicolon);
   }
   void test_parseExpression_assign() {
-    AssignmentExpression expression = ParserTestCase.parse4("parseExpression", "x = y", []);
+    AssignmentExpression expression = ParserTestCase.parse5("parseExpression", "x = y", []);
     JUnitTestCase.assertNotNull(expression.leftHandSide);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.EQ, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightHandSide);
   }
   void test_parseExpression_comparison() {
-    BinaryExpression expression = ParserTestCase.parse4("parseExpression", "--a.b == c", []);
+    BinaryExpression expression = ParserTestCase.parse5("parseExpression", "--a.b == c", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.EQ_EQ, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseExpression_invokeFunctionExpression() {
-    FunctionExpressionInvocation invocation = ParserTestCase.parse4("parseExpression", "(a) {return a + a;} (3)", []);
+    FunctionExpressionInvocation invocation = ParserTestCase.parse5("parseExpression", "(a) {return a + a;} (3)", []);
     EngineTestCase.assertInstanceOf(FunctionExpression, invocation.function);
-    FunctionExpression expression = invocation.function as FunctionExpression;
+    FunctionExpression expression = (invocation.function as FunctionExpression);
     JUnitTestCase.assertNotNull(expression.parameters);
     JUnitTestCase.assertNotNull(expression.body);
     ArgumentList list = invocation.argumentList;
@@ -2439,75 +2439,75 @@
     EngineTestCase.assertSize(1, list.arguments);
   }
   void test_parseExpression_superMethodInvocation() {
-    MethodInvocation invocation = ParserTestCase.parse4("parseExpression", "super.m()", []);
+    MethodInvocation invocation = ParserTestCase.parse5("parseExpression", "super.m()", []);
     JUnitTestCase.assertNotNull(invocation.target);
     JUnitTestCase.assertNotNull(invocation.methodName);
     JUnitTestCase.assertNotNull(invocation.argumentList);
   }
   void test_parseExpressionList_multiple() {
-    List<Expression> result = ParserTestCase.parse4("parseExpressionList", "1, 2, 3", []);
+    List<Expression> result = ParserTestCase.parse5("parseExpressionList", "1, 2, 3", []);
     EngineTestCase.assertSize(3, result);
   }
   void test_parseExpressionList_single() {
-    List<Expression> result = ParserTestCase.parse4("parseExpressionList", "1", []);
+    List<Expression> result = ParserTestCase.parse5("parseExpressionList", "1", []);
     EngineTestCase.assertSize(1, result);
   }
   void test_parseExpressionWithoutCascade_assign() {
-    AssignmentExpression expression = ParserTestCase.parse4("parseExpressionWithoutCascade", "x = y", []);
+    AssignmentExpression expression = ParserTestCase.parse5("parseExpressionWithoutCascade", "x = y", []);
     JUnitTestCase.assertNotNull(expression.leftHandSide);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.EQ, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightHandSide);
   }
   void test_parseExpressionWithoutCascade_comparison() {
-    BinaryExpression expression = ParserTestCase.parse4("parseExpressionWithoutCascade", "--a.b == c", []);
+    BinaryExpression expression = ParserTestCase.parse5("parseExpressionWithoutCascade", "--a.b == c", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.EQ_EQ, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseExpressionWithoutCascade_superMethodInvocation() {
-    MethodInvocation invocation = ParserTestCase.parse4("parseExpressionWithoutCascade", "super.m()", []);
+    MethodInvocation invocation = ParserTestCase.parse5("parseExpressionWithoutCascade", "super.m()", []);
     JUnitTestCase.assertNotNull(invocation.target);
     JUnitTestCase.assertNotNull(invocation.methodName);
     JUnitTestCase.assertNotNull(invocation.argumentList);
   }
   void test_parseExtendsClause() {
-    ExtendsClause clause = ParserTestCase.parse4("parseExtendsClause", "extends B", []);
+    ExtendsClause clause = ParserTestCase.parse5("parseExtendsClause", "extends B", []);
     JUnitTestCase.assertNotNull(clause.keyword);
     JUnitTestCase.assertNotNull(clause.superclass);
     EngineTestCase.assertInstanceOf(TypeName, clause.superclass);
   }
   void test_parseFinalConstVarOrType_const_noType() {
     FinalConstVarOrType result = ParserTestCase.parse("parseFinalConstVarOrType", <Object> [false], "const");
-    Token keyword30 = result.keyword;
-    JUnitTestCase.assertNotNull(keyword30);
-    JUnitTestCase.assertEquals(TokenType.KEYWORD, keyword30.type);
-    JUnitTestCase.assertEquals(Keyword.CONST, (keyword30 as KeywordToken).keyword);
+    Token keyword29 = result.keyword;
+    JUnitTestCase.assertNotNull(keyword29);
+    JUnitTestCase.assertEquals(TokenType.KEYWORD, keyword29.type);
+    JUnitTestCase.assertEquals(Keyword.CONST, ((keyword29 as KeywordToken)).keyword);
     JUnitTestCase.assertNull(result.type);
   }
   void test_parseFinalConstVarOrType_const_type() {
     FinalConstVarOrType result = ParserTestCase.parse("parseFinalConstVarOrType", <Object> [false], "const A a");
-    Token keyword31 = result.keyword;
-    JUnitTestCase.assertNotNull(keyword31);
-    JUnitTestCase.assertEquals(TokenType.KEYWORD, keyword31.type);
-    JUnitTestCase.assertEquals(Keyword.CONST, (keyword31 as KeywordToken).keyword);
+    Token keyword30 = result.keyword;
+    JUnitTestCase.assertNotNull(keyword30);
+    JUnitTestCase.assertEquals(TokenType.KEYWORD, keyword30.type);
+    JUnitTestCase.assertEquals(Keyword.CONST, ((keyword30 as KeywordToken)).keyword);
     JUnitTestCase.assertNotNull(result.type);
   }
   void test_parseFinalConstVarOrType_final_noType() {
     FinalConstVarOrType result = ParserTestCase.parse("parseFinalConstVarOrType", <Object> [false], "final");
-    Token keyword32 = result.keyword;
-    JUnitTestCase.assertNotNull(keyword32);
-    JUnitTestCase.assertEquals(TokenType.KEYWORD, keyword32.type);
-    JUnitTestCase.assertEquals(Keyword.FINAL, (keyword32 as KeywordToken).keyword);
+    Token keyword31 = result.keyword;
+    JUnitTestCase.assertNotNull(keyword31);
+    JUnitTestCase.assertEquals(TokenType.KEYWORD, keyword31.type);
+    JUnitTestCase.assertEquals(Keyword.FINAL, ((keyword31 as KeywordToken)).keyword);
     JUnitTestCase.assertNull(result.type);
   }
   void test_parseFinalConstVarOrType_final_type() {
     FinalConstVarOrType result = ParserTestCase.parse("parseFinalConstVarOrType", <Object> [false], "final A a");
-    Token keyword33 = result.keyword;
-    JUnitTestCase.assertNotNull(keyword33);
-    JUnitTestCase.assertEquals(TokenType.KEYWORD, keyword33.type);
-    JUnitTestCase.assertEquals(Keyword.FINAL, (keyword33 as KeywordToken).keyword);
+    Token keyword32 = result.keyword;
+    JUnitTestCase.assertNotNull(keyword32);
+    JUnitTestCase.assertEquals(TokenType.KEYWORD, keyword32.type);
+    JUnitTestCase.assertEquals(Keyword.FINAL, ((keyword32 as KeywordToken)).keyword);
     JUnitTestCase.assertNotNull(result.type);
   }
   void test_parseFinalConstVarOrType_type_parameterized() {
@@ -2532,16 +2532,16 @@
   }
   void test_parseFinalConstVarOrType_var() {
     FinalConstVarOrType result = ParserTestCase.parse("parseFinalConstVarOrType", <Object> [false], "var");
-    Token keyword34 = result.keyword;
-    JUnitTestCase.assertNotNull(keyword34);
-    JUnitTestCase.assertEquals(TokenType.KEYWORD, keyword34.type);
-    JUnitTestCase.assertEquals(Keyword.VAR, (keyword34 as KeywordToken).keyword);
+    Token keyword33 = result.keyword;
+    JUnitTestCase.assertNotNull(keyword33);
+    JUnitTestCase.assertEquals(TokenType.KEYWORD, keyword33.type);
+    JUnitTestCase.assertEquals(Keyword.VAR, ((keyword33 as KeywordToken)).keyword);
     JUnitTestCase.assertNull(result.type);
   }
   void test_parseFormalParameter_final_withType_named() {
     ParameterKind kind = ParameterKind.NAMED;
     DefaultFormalParameter parameter = ParserTestCase.parse("parseFormalParameter", <Object> [kind], "final A a : null");
-    SimpleFormalParameter simpleParameter = parameter.parameter as SimpleFormalParameter;
+    SimpleFormalParameter simpleParameter = (parameter.parameter as SimpleFormalParameter);
     JUnitTestCase.assertNotNull(simpleParameter.identifier);
     JUnitTestCase.assertNotNull(simpleParameter.keyword);
     JUnitTestCase.assertNotNull(simpleParameter.type);
@@ -2561,7 +2561,7 @@
   void test_parseFormalParameter_final_withType_positional() {
     ParameterKind kind = ParameterKind.POSITIONAL;
     DefaultFormalParameter parameter = ParserTestCase.parse("parseFormalParameter", <Object> [kind], "final A a = null");
-    SimpleFormalParameter simpleParameter = parameter.parameter as SimpleFormalParameter;
+    SimpleFormalParameter simpleParameter = (parameter.parameter as SimpleFormalParameter);
     JUnitTestCase.assertNotNull(simpleParameter.identifier);
     JUnitTestCase.assertNotNull(simpleParameter.keyword);
     JUnitTestCase.assertNotNull(simpleParameter.type);
@@ -2573,7 +2573,7 @@
   void test_parseFormalParameter_nonFinal_withType_named() {
     ParameterKind kind = ParameterKind.NAMED;
     DefaultFormalParameter parameter = ParserTestCase.parse("parseFormalParameter", <Object> [kind], "A a : null");
-    SimpleFormalParameter simpleParameter = parameter.parameter as SimpleFormalParameter;
+    SimpleFormalParameter simpleParameter = (parameter.parameter as SimpleFormalParameter);
     JUnitTestCase.assertNotNull(simpleParameter.identifier);
     JUnitTestCase.assertNull(simpleParameter.keyword);
     JUnitTestCase.assertNotNull(simpleParameter.type);
@@ -2593,7 +2593,7 @@
   void test_parseFormalParameter_nonFinal_withType_positional() {
     ParameterKind kind = ParameterKind.POSITIONAL;
     DefaultFormalParameter parameter = ParserTestCase.parse("parseFormalParameter", <Object> [kind], "A a = null");
-    SimpleFormalParameter simpleParameter = parameter.parameter as SimpleFormalParameter;
+    SimpleFormalParameter simpleParameter = (parameter.parameter as SimpleFormalParameter);
     JUnitTestCase.assertNotNull(simpleParameter.identifier);
     JUnitTestCase.assertNull(simpleParameter.keyword);
     JUnitTestCase.assertNotNull(simpleParameter.type);
@@ -2613,7 +2613,7 @@
   void test_parseFormalParameter_var_named() {
     ParameterKind kind = ParameterKind.NAMED;
     DefaultFormalParameter parameter = ParserTestCase.parse("parseFormalParameter", <Object> [kind], "var a : null");
-    SimpleFormalParameter simpleParameter = parameter.parameter as SimpleFormalParameter;
+    SimpleFormalParameter simpleParameter = (parameter.parameter as SimpleFormalParameter);
     JUnitTestCase.assertNotNull(simpleParameter.identifier);
     JUnitTestCase.assertNotNull(simpleParameter.keyword);
     JUnitTestCase.assertNull(simpleParameter.type);
@@ -2625,7 +2625,7 @@
   void test_parseFormalParameter_var_positional() {
     ParameterKind kind = ParameterKind.POSITIONAL;
     DefaultFormalParameter parameter = ParserTestCase.parse("parseFormalParameter", <Object> [kind], "var a = null");
-    SimpleFormalParameter simpleParameter = parameter.parameter as SimpleFormalParameter;
+    SimpleFormalParameter simpleParameter = (parameter.parameter as SimpleFormalParameter);
     JUnitTestCase.assertNotNull(simpleParameter.identifier);
     JUnitTestCase.assertNotNull(simpleParameter.keyword);
     JUnitTestCase.assertNull(simpleParameter.type);
@@ -2635,7 +2635,7 @@
     JUnitTestCase.assertEquals(kind, parameter.kind);
   }
   void test_parseFormalParameterList_empty() {
-    FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "()", []);
+    FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "()", []);
     JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
     JUnitTestCase.assertNull(parameterList.leftDelimiter);
     EngineTestCase.assertSize(0, parameterList.parameters);
@@ -2643,7 +2643,7 @@
     JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
   }
   void test_parseFormalParameterList_named_multiple() {
-    FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "({A a : 1, B b, C c : 3})", []);
+    FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "({A a : 1, B b, C c : 3})", []);
     JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
     JUnitTestCase.assertNotNull(parameterList.leftDelimiter);
     EngineTestCase.assertSize(3, parameterList.parameters);
@@ -2651,7 +2651,7 @@
     JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
   }
   void test_parseFormalParameterList_named_single() {
-    FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "({A a})", []);
+    FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "({A a})", []);
     JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
     JUnitTestCase.assertNotNull(parameterList.leftDelimiter);
     EngineTestCase.assertSize(1, parameterList.parameters);
@@ -2659,7 +2659,7 @@
     JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
   }
   void test_parseFormalParameterList_normal_multiple() {
-    FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "(A a, B b, C c)", []);
+    FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "(A a, B b, C c)", []);
     JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
     JUnitTestCase.assertNull(parameterList.leftDelimiter);
     EngineTestCase.assertSize(3, parameterList.parameters);
@@ -2667,7 +2667,7 @@
     JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
   }
   void test_parseFormalParameterList_normal_named() {
-    FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "(A a, {B b})", []);
+    FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "(A a, {B b})", []);
     JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
     JUnitTestCase.assertNotNull(parameterList.leftDelimiter);
     EngineTestCase.assertSize(2, parameterList.parameters);
@@ -2675,7 +2675,7 @@
     JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
   }
   void test_parseFormalParameterList_normal_positional() {
-    FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "(A a, [B b])", []);
+    FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "(A a, [B b])", []);
     JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
     JUnitTestCase.assertNotNull(parameterList.leftDelimiter);
     EngineTestCase.assertSize(2, parameterList.parameters);
@@ -2683,7 +2683,7 @@
     JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
   }
   void test_parseFormalParameterList_normal_single() {
-    FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "(A a)", []);
+    FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "(A a)", []);
     JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
     JUnitTestCase.assertNull(parameterList.leftDelimiter);
     EngineTestCase.assertSize(1, parameterList.parameters);
@@ -2691,7 +2691,7 @@
     JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
   }
   void test_parseFormalParameterList_positional_multiple() {
-    FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "([A a = null, B b, C c = null])", []);
+    FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "([A a = null, B b, C c = null])", []);
     JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
     JUnitTestCase.assertNotNull(parameterList.leftDelimiter);
     EngineTestCase.assertSize(3, parameterList.parameters);
@@ -2699,7 +2699,7 @@
     JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
   }
   void test_parseFormalParameterList_positional_single() {
-    FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "([A a = null])", []);
+    FormalParameterList parameterList = ParserTestCase.parse5("parseFormalParameterList", "([A a = null])", []);
     JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
     JUnitTestCase.assertNotNull(parameterList.leftDelimiter);
     EngineTestCase.assertSize(1, parameterList.parameters);
@@ -2707,7 +2707,7 @@
     JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
   }
   void test_parseForStatement_each_identifier() {
-    ForEachStatement statement = ParserTestCase.parse4("parseForStatement", "for (element in list) {}", []);
+    ForEachStatement statement = ParserTestCase.parse5("parseForStatement", "for (element in list) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.loopParameter);
@@ -2717,7 +2717,7 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_each_noType() {
-    ForEachStatement statement = ParserTestCase.parse4("parseForStatement", "for (element in list) {}", []);
+    ForEachStatement statement = ParserTestCase.parse5("parseForStatement", "for (element in list) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.loopParameter);
@@ -2727,7 +2727,7 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_each_type() {
-    ForEachStatement statement = ParserTestCase.parse4("parseForStatement", "for (A element in list) {}", []);
+    ForEachStatement statement = ParserTestCase.parse5("parseForStatement", "for (A element in list) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.loopParameter);
@@ -2737,7 +2737,7 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_each_var() {
-    ForEachStatement statement = ParserTestCase.parse4("parseForStatement", "for (var element in list) {}", []);
+    ForEachStatement statement = ParserTestCase.parse5("parseForStatement", "for (var element in list) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.loopParameter);
@@ -2747,7 +2747,7 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_loop_c() {
-    ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (; i < count;) {}", []);
+    ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (; i < count;) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNull(statement.variables);
@@ -2760,7 +2760,7 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_loop_cu() {
-    ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (; i < count; i++) {}", []);
+    ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (; i < count; i++) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNull(statement.variables);
@@ -2773,7 +2773,7 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_loop_ecu() {
-    ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (i--; i < count; i++) {}", []);
+    ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (i--; i < count; i++) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNull(statement.variables);
@@ -2786,12 +2786,12 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_loop_i() {
-    ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (var i = 0;;) {}", []);
+    ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (var i = 0;;) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
-    VariableDeclarationList variables10 = statement.variables;
-    JUnitTestCase.assertNotNull(variables10);
-    EngineTestCase.assertSize(1, variables10.variables);
+    VariableDeclarationList variables8 = statement.variables;
+    JUnitTestCase.assertNotNull(variables8);
+    EngineTestCase.assertSize(1, variables8.variables);
     JUnitTestCase.assertNull(statement.initialization);
     JUnitTestCase.assertNotNull(statement.leftSeparator);
     JUnitTestCase.assertNull(statement.condition);
@@ -2801,12 +2801,12 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_loop_ic() {
-    ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (var i = 0; i < count;) {}", []);
+    ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (var i = 0; i < count;) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
-    VariableDeclarationList variables11 = statement.variables;
-    JUnitTestCase.assertNotNull(variables11);
-    EngineTestCase.assertSize(1, variables11.variables);
+    VariableDeclarationList variables9 = statement.variables;
+    JUnitTestCase.assertNotNull(variables9);
+    EngineTestCase.assertSize(1, variables9.variables);
     JUnitTestCase.assertNull(statement.initialization);
     JUnitTestCase.assertNotNull(statement.leftSeparator);
     JUnitTestCase.assertNotNull(statement.condition);
@@ -2816,12 +2816,12 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_loop_icu() {
-    ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (var i = 0; i < count; i++) {}", []);
+    ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (var i = 0; i < count; i++) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
-    VariableDeclarationList variables12 = statement.variables;
-    JUnitTestCase.assertNotNull(variables12);
-    EngineTestCase.assertSize(1, variables12.variables);
+    VariableDeclarationList variables10 = statement.variables;
+    JUnitTestCase.assertNotNull(variables10);
+    EngineTestCase.assertSize(1, variables10.variables);
     JUnitTestCase.assertNull(statement.initialization);
     JUnitTestCase.assertNotNull(statement.leftSeparator);
     JUnitTestCase.assertNotNull(statement.condition);
@@ -2831,12 +2831,12 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_loop_iicuu() {
-    ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (int i = 0, j = count; i < j; i++, j--) {}", []);
+    ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (int i = 0, j = count; i < j; i++, j--) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
-    VariableDeclarationList variables13 = statement.variables;
-    JUnitTestCase.assertNotNull(variables13);
-    EngineTestCase.assertSize(2, variables13.variables);
+    VariableDeclarationList variables11 = statement.variables;
+    JUnitTestCase.assertNotNull(variables11);
+    EngineTestCase.assertSize(2, variables11.variables);
     JUnitTestCase.assertNull(statement.initialization);
     JUnitTestCase.assertNotNull(statement.leftSeparator);
     JUnitTestCase.assertNotNull(statement.condition);
@@ -2846,12 +2846,12 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_loop_iu() {
-    ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (var i = 0;; i++) {}", []);
+    ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (var i = 0;; i++) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
-    VariableDeclarationList variables14 = statement.variables;
-    JUnitTestCase.assertNotNull(variables14);
-    EngineTestCase.assertSize(1, variables14.variables);
+    VariableDeclarationList variables12 = statement.variables;
+    JUnitTestCase.assertNotNull(variables12);
+    EngineTestCase.assertSize(1, variables12.variables);
     JUnitTestCase.assertNull(statement.initialization);
     JUnitTestCase.assertNotNull(statement.leftSeparator);
     JUnitTestCase.assertNull(statement.condition);
@@ -2861,7 +2861,7 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseForStatement_loop_u() {
-    ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (;; i++) {}", []);
+    ForStatement statement = ParserTestCase.parse5("parseForStatement", "for (;; i++) {}", []);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNull(statement.variables);
@@ -2889,7 +2889,7 @@
   }
   void test_parseFunctionDeclaration_function() {
     Comment comment = Comment.createDocumentationComment(new List<Token>.fixedLength(0));
-    TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
+    TypeName returnType = new TypeName.full(new SimpleIdentifier.full(null), null);
     FunctionDeclaration declaration = ParserTestCase.parse("parseFunctionDeclaration", <Object> [commentAndMetadata(comment, []), null, returnType, false], "f() {}");
     JUnitTestCase.assertEquals(comment, declaration.documentationComment);
     JUnitTestCase.assertEquals(returnType, declaration.returnType);
@@ -2902,7 +2902,7 @@
   }
   void test_parseFunctionDeclaration_function_inStatement() {
     Comment comment = Comment.createDocumentationComment(new List<Token>.fixedLength(0));
-    TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
+    TypeName returnType = new TypeName.full(new SimpleIdentifier.full(null), null);
     FunctionDeclaration declaration = ParserTestCase.parse("parseFunctionDeclaration", <Object> [commentAndMetadata(comment, []), null, returnType, true], "f() {};");
     JUnitTestCase.assertEquals(comment, declaration.documentationComment);
     JUnitTestCase.assertEquals(returnType, declaration.returnType);
@@ -2915,7 +2915,7 @@
   }
   void test_parseFunctionDeclaration_getter() {
     Comment comment = Comment.createDocumentationComment(new List<Token>.fixedLength(0));
-    TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
+    TypeName returnType = new TypeName.full(new SimpleIdentifier.full(null), null);
     FunctionDeclaration declaration = ParserTestCase.parse("parseFunctionDeclaration", <Object> [commentAndMetadata(comment, []), null, returnType, false], "get p => 0;");
     JUnitTestCase.assertEquals(comment, declaration.documentationComment);
     JUnitTestCase.assertEquals(returnType, declaration.returnType);
@@ -2928,7 +2928,7 @@
   }
   void test_parseFunctionDeclaration_setter() {
     Comment comment = Comment.createDocumentationComment(new List<Token>.fixedLength(0));
-    TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
+    TypeName returnType = new TypeName.full(new SimpleIdentifier.full(null), null);
     FunctionDeclaration declaration = ParserTestCase.parse("parseFunctionDeclaration", <Object> [commentAndMetadata(comment, []), null, returnType, false], "set p(v) {}");
     JUnitTestCase.assertEquals(comment, declaration.documentationComment);
     JUnitTestCase.assertEquals(returnType, declaration.returnType);
@@ -2940,23 +2940,23 @@
     JUnitTestCase.assertNotNull(declaration.propertyKeyword);
   }
   void test_parseFunctionDeclarationStatement() {
-    FunctionDeclarationStatement statement = ParserTestCase.parse4("parseFunctionDeclarationStatement", "void f(int p) => p * 2;", []);
+    FunctionDeclarationStatement statement = ParserTestCase.parse5("parseFunctionDeclarationStatement", "void f(int p) => p * 2;", []);
     JUnitTestCase.assertNotNull(statement.functionDeclaration);
   }
   void test_parseFunctionExpression_body_inExpression() {
-    FunctionExpression expression = ParserTestCase.parse4("parseFunctionExpression", "(int i) => i++", []);
+    FunctionExpression expression = ParserTestCase.parse5("parseFunctionExpression", "(int i) => i++", []);
     JUnitTestCase.assertNotNull(expression.body);
     JUnitTestCase.assertNotNull(expression.parameters);
-    JUnitTestCase.assertNull((expression.body as ExpressionFunctionBody).semicolon);
+    JUnitTestCase.assertNull(((expression.body as ExpressionFunctionBody)).semicolon);
   }
   void test_parseFunctionExpression_minimal() {
-    FunctionExpression expression = ParserTestCase.parse4("parseFunctionExpression", "() {}", []);
+    FunctionExpression expression = ParserTestCase.parse5("parseFunctionExpression", "() {}", []);
     JUnitTestCase.assertNotNull(expression.body);
     JUnitTestCase.assertNotNull(expression.parameters);
   }
   void test_parseGetter_nonStatic() {
     Comment comment = Comment.createDocumentationComment(new List<Token>.fixedLength(0));
-    TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
+    TypeName returnType = new TypeName.full(new SimpleIdentifier.full(null), null);
     MethodDeclaration method = ParserTestCase.parse("parseGetter", <Object> [commentAndMetadata(comment, []), null, null, returnType], "get a;");
     JUnitTestCase.assertNotNull(method.body);
     JUnitTestCase.assertEquals(comment, method.documentationComment);
@@ -2971,7 +2971,7 @@
   void test_parseGetter_static() {
     Comment comment = Comment.createDocumentationComment(new List<Token>.fixedLength(0));
     Token staticKeyword = TokenFactory.token(Keyword.STATIC);
-    TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
+    TypeName returnType = new TypeName.full(new SimpleIdentifier.full(null), null);
     MethodDeclaration method = ParserTestCase.parse("parseGetter", <Object> [commentAndMetadata(comment, []), null, staticKeyword, returnType], "get a;");
     JUnitTestCase.assertNotNull(method.body);
     JUnitTestCase.assertEquals(comment, method.documentationComment);
@@ -2984,15 +2984,15 @@
     JUnitTestCase.assertEquals(returnType, method.returnType);
   }
   void test_parseIdentifierList_multiple() {
-    List<SimpleIdentifier> list = ParserTestCase.parse4("parseIdentifierList", "a, b, c", []);
+    List<SimpleIdentifier> list = ParserTestCase.parse5("parseIdentifierList", "a, b, c", []);
     EngineTestCase.assertSize(3, list);
   }
   void test_parseIdentifierList_single() {
-    List<SimpleIdentifier> list = ParserTestCase.parse4("parseIdentifierList", "a", []);
+    List<SimpleIdentifier> list = ParserTestCase.parse5("parseIdentifierList", "a", []);
     EngineTestCase.assertSize(1, list);
   }
   void test_parseIfStatement_else_block() {
-    IfStatement statement = ParserTestCase.parse4("parseIfStatement", "if (x) {} else {}", []);
+    IfStatement statement = ParserTestCase.parse5("parseIfStatement", "if (x) {} else {}", []);
     JUnitTestCase.assertNotNull(statement.ifKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.condition);
@@ -3002,7 +3002,7 @@
     JUnitTestCase.assertNotNull(statement.elseStatement);
   }
   void test_parseIfStatement_else_statement() {
-    IfStatement statement = ParserTestCase.parse4("parseIfStatement", "if (x) f(x); else f(y);", []);
+    IfStatement statement = ParserTestCase.parse5("parseIfStatement", "if (x) f(x); else f(y);", []);
     JUnitTestCase.assertNotNull(statement.ifKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.condition);
@@ -3012,7 +3012,7 @@
     JUnitTestCase.assertNotNull(statement.elseStatement);
   }
   void test_parseIfStatement_noElse_block() {
-    IfStatement statement = ParserTestCase.parse4("parseIfStatement", "if (x) {}", []);
+    IfStatement statement = ParserTestCase.parse5("parseIfStatement", "if (x) {}", []);
     JUnitTestCase.assertNotNull(statement.ifKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.condition);
@@ -3022,7 +3022,7 @@
     JUnitTestCase.assertNull(statement.elseStatement);
   }
   void test_parseIfStatement_noElse_statement() {
-    IfStatement statement = ParserTestCase.parse4("parseIfStatement", "if (x) f(x);", []);
+    IfStatement statement = ParserTestCase.parse5("parseIfStatement", "if (x) f(x);", []);
     JUnitTestCase.assertNotNull(statement.ifKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.condition);
@@ -3032,19 +3032,19 @@
     JUnitTestCase.assertNull(statement.elseStatement);
   }
   void test_parseImplementsClause_multiple() {
-    ImplementsClause clause = ParserTestCase.parse4("parseImplementsClause", "implements A, B, C", []);
+    ImplementsClause clause = ParserTestCase.parse5("parseImplementsClause", "implements A, B, C", []);
     EngineTestCase.assertSize(3, clause.interfaces);
     JUnitTestCase.assertNotNull(clause.keyword);
   }
   void test_parseImplementsClause_single() {
-    ImplementsClause clause = ParserTestCase.parse4("parseImplementsClause", "implements A", []);
+    ImplementsClause clause = ParserTestCase.parse5("parseImplementsClause", "implements A", []);
     EngineTestCase.assertSize(1, clause.interfaces);
     JUnitTestCase.assertNotNull(clause.keyword);
   }
   void test_parseImportDirective_hide() {
     ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart' hide A, B;");
     JUnitTestCase.assertNotNull(directive.keyword);
-    JUnitTestCase.assertNotNull(directive.libraryUri);
+    JUnitTestCase.assertNotNull(directive.uri);
     JUnitTestCase.assertNull(directive.asToken);
     JUnitTestCase.assertNull(directive.prefix);
     EngineTestCase.assertSize(1, directive.combinators);
@@ -3053,7 +3053,7 @@
   void test_parseImportDirective_noCombinator() {
     ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart';");
     JUnitTestCase.assertNotNull(directive.keyword);
-    JUnitTestCase.assertNotNull(directive.libraryUri);
+    JUnitTestCase.assertNotNull(directive.uri);
     JUnitTestCase.assertNull(directive.asToken);
     JUnitTestCase.assertNull(directive.prefix);
     EngineTestCase.assertSize(0, directive.combinators);
@@ -3062,7 +3062,7 @@
   void test_parseImportDirective_prefix() {
     ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart' as a;");
     JUnitTestCase.assertNotNull(directive.keyword);
-    JUnitTestCase.assertNotNull(directive.libraryUri);
+    JUnitTestCase.assertNotNull(directive.uri);
     JUnitTestCase.assertNotNull(directive.asToken);
     JUnitTestCase.assertNotNull(directive.prefix);
     EngineTestCase.assertSize(0, directive.combinators);
@@ -3071,7 +3071,7 @@
   void test_parseImportDirective_prefix_hide_show() {
     ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart' as a hide A show B;");
     JUnitTestCase.assertNotNull(directive.keyword);
-    JUnitTestCase.assertNotNull(directive.libraryUri);
+    JUnitTestCase.assertNotNull(directive.uri);
     JUnitTestCase.assertNotNull(directive.asToken);
     JUnitTestCase.assertNotNull(directive.prefix);
     EngineTestCase.assertSize(2, directive.combinators);
@@ -3080,7 +3080,7 @@
   void test_parseImportDirective_prefix_show_hide() {
     ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart' as a show B hide A;");
     JUnitTestCase.assertNotNull(directive.keyword);
-    JUnitTestCase.assertNotNull(directive.libraryUri);
+    JUnitTestCase.assertNotNull(directive.uri);
     JUnitTestCase.assertNotNull(directive.asToken);
     JUnitTestCase.assertNotNull(directive.prefix);
     EngineTestCase.assertSize(2, directive.combinators);
@@ -3089,7 +3089,7 @@
   void test_parseImportDirective_show() {
     ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart' show A, B;");
     JUnitTestCase.assertNotNull(directive.keyword);
-    JUnitTestCase.assertNotNull(directive.libraryUri);
+    JUnitTestCase.assertNotNull(directive.uri);
     JUnitTestCase.assertNull(directive.asToken);
     JUnitTestCase.assertNull(directive.prefix);
     EngineTestCase.assertSize(1, directive.combinators);
@@ -3098,14 +3098,14 @@
   void test_parseInitializedIdentifierList_type() {
     Comment comment = Comment.createDocumentationComment(new List<Token>.fixedLength(0));
     Token staticKeyword = TokenFactory.token(Keyword.STATIC);
-    TypeName type = new TypeName(new SimpleIdentifier(null), null);
+    TypeName type = new TypeName.full(new SimpleIdentifier.full(null), null);
     FieldDeclaration declaration = ParserTestCase.parse("parseInitializedIdentifierList", <Object> [commentAndMetadata(comment, []), staticKeyword, null, type], "a = 1, b, c = 3;");
     JUnitTestCase.assertEquals(comment, declaration.documentationComment);
-    VariableDeclarationList fields5 = declaration.fields;
-    JUnitTestCase.assertNotNull(fields5);
-    JUnitTestCase.assertNull(fields5.keyword);
-    JUnitTestCase.assertEquals(type, fields5.type);
-    EngineTestCase.assertSize(3, fields5.variables);
+    VariableDeclarationList fields3 = declaration.fields;
+    JUnitTestCase.assertNotNull(fields3);
+    JUnitTestCase.assertNull(fields3.keyword);
+    JUnitTestCase.assertEquals(type, fields3.type);
+    EngineTestCase.assertSize(3, fields3.variables);
     JUnitTestCase.assertEquals(staticKeyword, declaration.keyword);
     JUnitTestCase.assertNotNull(declaration.semicolon);
   }
@@ -3115,11 +3115,11 @@
     Token varKeyword = TokenFactory.token(Keyword.VAR);
     FieldDeclaration declaration = ParserTestCase.parse("parseInitializedIdentifierList", <Object> [commentAndMetadata(comment, []), staticKeyword, varKeyword, null], "a = 1, b, c = 3;");
     JUnitTestCase.assertEquals(comment, declaration.documentationComment);
-    VariableDeclarationList fields6 = declaration.fields;
-    JUnitTestCase.assertNotNull(fields6);
-    JUnitTestCase.assertEquals(varKeyword, fields6.keyword);
-    JUnitTestCase.assertNull(fields6.type);
-    EngineTestCase.assertSize(3, fields6.variables);
+    VariableDeclarationList fields4 = declaration.fields;
+    JUnitTestCase.assertNotNull(fields4);
+    JUnitTestCase.assertEquals(varKeyword, fields4.keyword);
+    JUnitTestCase.assertNull(fields4.type);
+    EngineTestCase.assertSize(3, fields4.variables);
     JUnitTestCase.assertEquals(staticKeyword, declaration.keyword);
     JUnitTestCase.assertNotNull(declaration.semicolon);
   }
@@ -3175,17 +3175,17 @@
   }
   void test_parseLibraryIdentifier_multiple() {
     String name = "a.b.c";
-    LibraryIdentifier identifier = ParserTestCase.parse4("parseLibraryIdentifier", name, []);
+    LibraryIdentifier identifier = ParserTestCase.parse5("parseLibraryIdentifier", name, []);
     JUnitTestCase.assertEquals(name, identifier.name);
   }
   void test_parseLibraryIdentifier_single() {
     String name = "a";
-    LibraryIdentifier identifier = ParserTestCase.parse4("parseLibraryIdentifier", name, []);
+    LibraryIdentifier identifier = ParserTestCase.parse5("parseLibraryIdentifier", name, []);
     JUnitTestCase.assertEquals(name, identifier.name);
   }
   void test_parseListLiteral_empty_oneToken() {
     Token token9 = TokenFactory.token(Keyword.CONST);
-    TypeArgumentList typeArguments = new TypeArgumentList(null, null, null);
+    TypeArgumentList typeArguments = new TypeArgumentList.full(null, null, null);
     ListLiteral literal = ParserTestCase.parse("parseListLiteral", <Object> [token9, typeArguments], "[]");
     JUnitTestCase.assertEquals(token9, literal.modifier);
     JUnitTestCase.assertEquals(typeArguments, literal.typeArguments);
@@ -3195,7 +3195,7 @@
   }
   void test_parseListLiteral_empty_twoTokens() {
     Token token10 = TokenFactory.token(Keyword.CONST);
-    TypeArgumentList typeArguments = new TypeArgumentList(null, null, null);
+    TypeArgumentList typeArguments = new TypeArgumentList.full(null, null, null);
     ListLiteral literal = ParserTestCase.parse("parseListLiteral", <Object> [token10, typeArguments], "[ ]");
     JUnitTestCase.assertEquals(token10, literal.modifier);
     JUnitTestCase.assertEquals(typeArguments, literal.typeArguments);
@@ -3252,14 +3252,14 @@
     JUnitTestCase.assertNotNull(literal.rightBracket);
   }
   void test_parseLogicalAndExpression() {
-    BinaryExpression expression = ParserTestCase.parse4("parseLogicalAndExpression", "x && y", []);
+    BinaryExpression expression = ParserTestCase.parse5("parseLogicalAndExpression", "x && y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.AMPERSAND_AMPERSAND, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseLogicalOrExpression() {
-    BinaryExpression expression = ParserTestCase.parse4("parseLogicalOrExpression", "x || y", []);
+    BinaryExpression expression = ParserTestCase.parse5("parseLogicalOrExpression", "x || y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.BAR_BAR, expression.operator.type);
@@ -3267,7 +3267,7 @@
   }
   void test_parseMapLiteral_empty() {
     Token token11 = TokenFactory.token(Keyword.CONST);
-    TypeArgumentList typeArguments = new TypeArgumentList(null, null, null);
+    TypeArgumentList typeArguments = new TypeArgumentList.full(null, null, null);
     MapLiteral literal = ParserTestCase.parse("parseMapLiteral", <Object> [token11, typeArguments], "{}");
     JUnitTestCase.assertEquals(token11, literal.modifier);
     JUnitTestCase.assertEquals(typeArguments, literal.typeArguments);
@@ -3288,55 +3288,55 @@
     JUnitTestCase.assertNotNull(literal.rightBracket);
   }
   void test_parseMapLiteralEntry() {
-    MapLiteralEntry entry = ParserTestCase.parse4("parseMapLiteralEntry", "'x' : y", []);
+    MapLiteralEntry entry = ParserTestCase.parse5("parseMapLiteralEntry", "'x' : y", []);
     JUnitTestCase.assertNotNull(entry.key);
     JUnitTestCase.assertNotNull(entry.separator);
     JUnitTestCase.assertNotNull(entry.value);
   }
   void test_parseModifiers_abstract() {
-    Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "abstract A", []);
+    Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "abstract A", []);
     JUnitTestCase.assertNotNull(modifiers.abstractKeyword);
   }
   void test_parseModifiers_const() {
-    Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "const A", []);
+    Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "const A", []);
     JUnitTestCase.assertNotNull(modifiers.constKeyword);
   }
   void test_parseModifiers_external() {
-    Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "external A", []);
+    Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "external A", []);
     JUnitTestCase.assertNotNull(modifiers.externalKeyword);
   }
   void test_parseModifiers_factory() {
-    Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "factory A", []);
+    Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "factory A", []);
     JUnitTestCase.assertNotNull(modifiers.factoryKeyword);
   }
   void test_parseModifiers_final() {
-    Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "final A", []);
+    Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "final A", []);
     JUnitTestCase.assertNotNull(modifiers.finalKeyword);
   }
   void test_parseModifiers_static() {
-    Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "static A", []);
+    Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "static A", []);
     JUnitTestCase.assertNotNull(modifiers.staticKeyword);
   }
   void test_parseModifiers_var() {
-    Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "var A", []);
+    Modifiers modifiers = ParserTestCase.parse5("parseModifiers", "var A", []);
     JUnitTestCase.assertNotNull(modifiers.varKeyword);
   }
   void test_parseMultiplicativeExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parse4("parseMultiplicativeExpression", "x * y", []);
+    BinaryExpression expression = ParserTestCase.parse5("parseMultiplicativeExpression", "x * y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.STAR, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseMultiplicativeExpression_super() {
-    BinaryExpression expression = ParserTestCase.parse4("parseMultiplicativeExpression", "super * y", []);
+    BinaryExpression expression = ParserTestCase.parse5("parseMultiplicativeExpression", "super * y", []);
     EngineTestCase.assertInstanceOf(SuperExpression, expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.STAR, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseNewExpression() {
-    InstanceCreationExpression expression = ParserTestCase.parse4("parseNewExpression", "new A()", []);
+    InstanceCreationExpression expression = ParserTestCase.parse5("parseNewExpression", "new A()", []);
     JUnitTestCase.assertNotNull(expression.keyword);
     ConstructorName name = expression.constructorName;
     JUnitTestCase.assertNotNull(name);
@@ -3346,56 +3346,56 @@
     JUnitTestCase.assertNotNull(expression.argumentList);
   }
   void test_parseNonLabeledStatement_const_list_empty() {
-    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "const [];", []);
+    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "const [];", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_const_list_nonEmpty() {
-    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "const [1, 2];", []);
+    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "const [1, 2];", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_const_map_empty() {
-    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "const {};", []);
+    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "const {};", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_const_map_nonEmpty() {
-    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "const {'a' : 1};", []);
+    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "const {'a' : 1};", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_const_object() {
-    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "const A();", []);
+    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "const A();", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_const_object_named_typeParameters() {
-    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "const A<B>.c();", []);
+    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "const A<B>.c();", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_constructorInvocation() {
-    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "new C().m();", []);
+    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "new C().m();", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_false() {
-    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "false;", []);
+    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "false;", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_functionDeclaration() {
-    ParserTestCase.parse4("parseNonLabeledStatement", "f() {};", []);
+    ParserTestCase.parse5("parseNonLabeledStatement", "f() {};", []);
   }
   void test_parseNonLabeledStatement_functionDeclaration_arguments() {
-    ParserTestCase.parse4("parseNonLabeledStatement", "f(void g()) {};", []);
+    ParserTestCase.parse5("parseNonLabeledStatement", "f(void g()) {};", []);
   }
   void test_parseNonLabeledStatement_functionExpressionIndex() {
-    ParserTestCase.parse4("parseNonLabeledStatement", "() {}[0] = null;", []);
+    ParserTestCase.parse5("parseNonLabeledStatement", "() {}[0] = null;", []);
   }
   void test_parseNonLabeledStatement_functionInvocation() {
-    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "f();", []);
+    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "f();", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_invokeFunctionExpression() {
-    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "(a) {return a + a;} (3);", []);
+    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "(a) {return a + a;} (3);", []);
     EngineTestCase.assertInstanceOf(FunctionExpressionInvocation, statement.expression);
-    FunctionExpressionInvocation invocation = statement.expression as FunctionExpressionInvocation;
+    FunctionExpressionInvocation invocation = (statement.expression as FunctionExpressionInvocation);
     EngineTestCase.assertInstanceOf(FunctionExpression, invocation.function);
-    FunctionExpression expression = invocation.function as FunctionExpression;
+    FunctionExpression expression = (invocation.function as FunctionExpression);
     JUnitTestCase.assertNotNull(expression.parameters);
     JUnitTestCase.assertNotNull(expression.body);
     ArgumentList list = invocation.argumentList;
@@ -3403,120 +3403,120 @@
     EngineTestCase.assertSize(1, list.arguments);
   }
   void test_parseNonLabeledStatement_null() {
-    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "null;", []);
+    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "null;", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_startingWithBuiltInIdentifier() {
-    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "library.getName();", []);
+    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "library.getName();", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_true() {
-    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "true;", []);
+    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "true;", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNonLabeledStatement_typeCast() {
-    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "double.NAN as num;", []);
+    ExpressionStatement statement = ParserTestCase.parse5("parseNonLabeledStatement", "double.NAN as num;", []);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseNormalFormalParameter_field_const_noType() {
-    FieldFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "const this.a)", []);
+    FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "const this.a)", []);
     JUnitTestCase.assertNotNull(parameter.keyword);
     JUnitTestCase.assertNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_field_const_type() {
-    FieldFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "const A this.a)", []);
+    FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "const A this.a)", []);
     JUnitTestCase.assertNotNull(parameter.keyword);
     JUnitTestCase.assertNotNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_field_final_noType() {
-    FieldFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "final this.a)", []);
+    FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "final this.a)", []);
     JUnitTestCase.assertNotNull(parameter.keyword);
     JUnitTestCase.assertNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_field_final_type() {
-    FieldFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "final A this.a)", []);
+    FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "final A this.a)", []);
     JUnitTestCase.assertNotNull(parameter.keyword);
     JUnitTestCase.assertNotNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_field_noType() {
-    FieldFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "this.a)", []);
+    FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "this.a)", []);
     JUnitTestCase.assertNull(parameter.keyword);
     JUnitTestCase.assertNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_field_type() {
-    FieldFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "A this.a)", []);
+    FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "A this.a)", []);
     JUnitTestCase.assertNull(parameter.keyword);
     JUnitTestCase.assertNotNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_field_var() {
-    FieldFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "var this.a)", []);
+    FieldFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "var this.a)", []);
     JUnitTestCase.assertNotNull(parameter.keyword);
     JUnitTestCase.assertNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_function_noType() {
-    FunctionTypedFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "a())", []);
+    FunctionTypedFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "a())", []);
     JUnitTestCase.assertNull(parameter.returnType);
     JUnitTestCase.assertNotNull(parameter.identifier);
     JUnitTestCase.assertNotNull(parameter.parameters);
   }
   void test_parseNormalFormalParameter_function_type() {
-    FunctionTypedFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "A a())", []);
+    FunctionTypedFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "A a())", []);
     JUnitTestCase.assertNotNull(parameter.returnType);
     JUnitTestCase.assertNotNull(parameter.identifier);
     JUnitTestCase.assertNotNull(parameter.parameters);
   }
   void test_parseNormalFormalParameter_function_void() {
-    FunctionTypedFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "void a())", []);
+    FunctionTypedFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "void a())", []);
     JUnitTestCase.assertNotNull(parameter.returnType);
     JUnitTestCase.assertNotNull(parameter.identifier);
     JUnitTestCase.assertNotNull(parameter.parameters);
   }
   void test_parseNormalFormalParameter_simple_const_noType() {
-    SimpleFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "const a)", []);
+    SimpleFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "const a)", []);
     JUnitTestCase.assertNotNull(parameter.keyword);
     JUnitTestCase.assertNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_simple_const_type() {
-    SimpleFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "const A a)", []);
+    SimpleFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "const A a)", []);
     JUnitTestCase.assertNotNull(parameter.keyword);
     JUnitTestCase.assertNotNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_simple_final_noType() {
-    SimpleFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "final a)", []);
+    SimpleFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "final a)", []);
     JUnitTestCase.assertNotNull(parameter.keyword);
     JUnitTestCase.assertNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_simple_final_type() {
-    SimpleFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "final A a)", []);
+    SimpleFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "final A a)", []);
     JUnitTestCase.assertNotNull(parameter.keyword);
     JUnitTestCase.assertNotNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_simple_noType() {
-    SimpleFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "a)", []);
+    SimpleFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "a)", []);
     JUnitTestCase.assertNull(parameter.keyword);
     JUnitTestCase.assertNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseNormalFormalParameter_simple_type() {
-    SimpleFormalParameter parameter = ParserTestCase.parse4("parseNormalFormalParameter", "A a)", []);
+    SimpleFormalParameter parameter = ParserTestCase.parse5("parseNormalFormalParameter", "A a)", []);
     JUnitTestCase.assertNull(parameter.keyword);
     JUnitTestCase.assertNotNull(parameter.type);
     JUnitTestCase.assertNotNull(parameter.identifier);
   }
   void test_parseOperator() {
     Comment comment = Comment.createDocumentationComment(new List<Token>.fixedLength(0));
-    TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
+    TypeName returnType = new TypeName.full(new SimpleIdentifier.full(null), null);
     MethodDeclaration method = ParserTestCase.parse("parseOperator", <Object> [commentAndMetadata(comment, []), null, returnType], "operator +(A a);");
     JUnitTestCase.assertNotNull(method.body);
     JUnitTestCase.assertEquals(comment, method.documentationComment);
@@ -3533,7 +3533,7 @@
   void test_parsePartDirective_part() {
     PartDirective directive = ParserTestCase.parse("parsePartDirective", <Object> [emptyCommentAndMetadata()], "part 'lib/lib.dart';");
     JUnitTestCase.assertNotNull(directive.partToken);
-    JUnitTestCase.assertNotNull(directive.partUri);
+    JUnitTestCase.assertNotNull(directive.uri);
     JUnitTestCase.assertNotNull(directive.semicolon);
   }
   void test_parsePartDirective_partOf() {
@@ -3544,144 +3544,144 @@
     JUnitTestCase.assertNotNull(directive.semicolon);
   }
   void test_parsePostfixExpression_decrement() {
-    PostfixExpression expression = ParserTestCase.parse4("parsePostfixExpression", "i--", []);
+    PostfixExpression expression = ParserTestCase.parse5("parsePostfixExpression", "i--", []);
     JUnitTestCase.assertNotNull(expression.operand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.MINUS_MINUS, expression.operator.type);
   }
   void test_parsePostfixExpression_increment() {
-    PostfixExpression expression = ParserTestCase.parse4("parsePostfixExpression", "i++", []);
+    PostfixExpression expression = ParserTestCase.parse5("parsePostfixExpression", "i++", []);
     JUnitTestCase.assertNotNull(expression.operand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.PLUS_PLUS, expression.operator.type);
   }
   void test_parsePostfixExpression_none_indexExpression() {
-    IndexExpression expression = ParserTestCase.parse4("parsePostfixExpression", "a[0]", []);
+    IndexExpression expression = ParserTestCase.parse5("parsePostfixExpression", "a[0]", []);
     JUnitTestCase.assertNotNull(expression.array);
     JUnitTestCase.assertNotNull(expression.index);
   }
   void test_parsePostfixExpression_none_methodInvocation() {
-    MethodInvocation expression = ParserTestCase.parse4("parsePostfixExpression", "a.m()", []);
+    MethodInvocation expression = ParserTestCase.parse5("parsePostfixExpression", "a.m()", []);
     JUnitTestCase.assertNotNull(expression.target);
     JUnitTestCase.assertNotNull(expression.methodName);
     JUnitTestCase.assertNotNull(expression.argumentList);
   }
   void test_parsePostfixExpression_none_propertyAccess() {
-    PrefixedIdentifier expression = ParserTestCase.parse4("parsePostfixExpression", "a.b", []);
+    PrefixedIdentifier expression = ParserTestCase.parse5("parsePostfixExpression", "a.b", []);
     JUnitTestCase.assertNotNull(expression.prefix);
     JUnitTestCase.assertNotNull(expression.identifier);
   }
   void test_parsePrefixedIdentifier_noPrefix() {
     String lexeme = "bar";
-    SimpleIdentifier identifier = ParserTestCase.parse4("parsePrefixedIdentifier", lexeme, []);
+    SimpleIdentifier identifier = ParserTestCase.parse5("parsePrefixedIdentifier", lexeme, []);
     JUnitTestCase.assertNotNull(identifier.token);
     JUnitTestCase.assertEquals(lexeme, identifier.name);
   }
   void test_parsePrefixedIdentifier_prefix() {
     String lexeme = "foo.bar";
-    PrefixedIdentifier identifier = ParserTestCase.parse4("parsePrefixedIdentifier", lexeme, []);
+    PrefixedIdentifier identifier = ParserTestCase.parse5("parsePrefixedIdentifier", lexeme, []);
     JUnitTestCase.assertEquals("foo", identifier.prefix.name);
     JUnitTestCase.assertNotNull(identifier.period);
     JUnitTestCase.assertEquals("bar", identifier.identifier.name);
   }
   void test_parsePrimaryExpression_argumentDefinitionTest() {
-    ArgumentDefinitionTest expression = ParserTestCase.parse4("parseArgumentDefinitionTest", "?a", []);
+    ArgumentDefinitionTest expression = ParserTestCase.parse5("parseArgumentDefinitionTest", "?a", []);
     JUnitTestCase.assertNotNull(expression.question);
     JUnitTestCase.assertNotNull(expression.identifier);
   }
   void test_parsePrimaryExpression_const() {
-    InstanceCreationExpression expression = ParserTestCase.parse4("parsePrimaryExpression", "const A()", []);
+    InstanceCreationExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "const A()", []);
     JUnitTestCase.assertNotNull(expression);
   }
   void test_parsePrimaryExpression_double() {
     String doubleLiteral = "3.2e4";
-    DoubleLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", doubleLiteral, []);
+    DoubleLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", doubleLiteral, []);
     JUnitTestCase.assertNotNull(literal.literal);
     JUnitTestCase.assertEquals(double.parse(doubleLiteral), literal.value);
   }
   void test_parsePrimaryExpression_false() {
-    BooleanLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "false", []);
+    BooleanLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "false", []);
     JUnitTestCase.assertNotNull(literal.literal);
     JUnitTestCase.assertFalse(literal.value);
   }
   void test_parsePrimaryExpression_function_arguments() {
-    FunctionExpression expression = ParserTestCase.parse4("parsePrimaryExpression", "(int i) => i + 1", []);
+    FunctionExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "(int i) => i + 1", []);
     JUnitTestCase.assertNotNull(expression.parameters);
     JUnitTestCase.assertNotNull(expression.body);
   }
   void test_parsePrimaryExpression_function_noArguments() {
-    FunctionExpression expression = ParserTestCase.parse4("parsePrimaryExpression", "() => 42", []);
+    FunctionExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "() => 42", []);
     JUnitTestCase.assertNotNull(expression.parameters);
     JUnitTestCase.assertNotNull(expression.body);
   }
   void test_parsePrimaryExpression_hex() {
     String hexLiteral = "3F";
-    IntegerLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "0x${hexLiteral}", []);
+    IntegerLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "0x${hexLiteral}", []);
     JUnitTestCase.assertNotNull(literal.literal);
     JUnitTestCase.assertEquals(int.parse(hexLiteral, radix: 16), literal.value);
   }
   void test_parsePrimaryExpression_identifier() {
-    SimpleIdentifier identifier = ParserTestCase.parse4("parsePrimaryExpression", "a", []);
+    SimpleIdentifier identifier = ParserTestCase.parse5("parsePrimaryExpression", "a", []);
     JUnitTestCase.assertNotNull(identifier);
   }
   void test_parsePrimaryExpression_int() {
     String intLiteral = "472";
-    IntegerLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", intLiteral, []);
+    IntegerLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", intLiteral, []);
     JUnitTestCase.assertNotNull(literal.literal);
     JUnitTestCase.assertEquals(int.parse(intLiteral), literal.value);
   }
   void test_parsePrimaryExpression_listLiteral() {
-    ListLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "[ ]", []);
+    ListLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "[ ]", []);
     JUnitTestCase.assertNotNull(literal);
   }
   void test_parsePrimaryExpression_listLiteral_index() {
-    ListLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "[]", []);
+    ListLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "[]", []);
     JUnitTestCase.assertNotNull(literal);
   }
   void test_parsePrimaryExpression_listLiteral_typed() {
-    ListLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "<A>[ ]", []);
+    ListLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "<A>[ ]", []);
     JUnitTestCase.assertNotNull(literal.typeArguments);
     EngineTestCase.assertSize(1, literal.typeArguments.arguments);
   }
   void test_parsePrimaryExpression_mapLiteral() {
-    MapLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "{}", []);
+    MapLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "{}", []);
     JUnitTestCase.assertNotNull(literal);
   }
   void test_parsePrimaryExpression_mapLiteral_typed() {
-    MapLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "<A>{}", []);
+    MapLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "<A>{}", []);
     JUnitTestCase.assertNotNull(literal.typeArguments);
     EngineTestCase.assertSize(1, literal.typeArguments.arguments);
   }
   void test_parsePrimaryExpression_new() {
-    InstanceCreationExpression expression = ParserTestCase.parse4("parsePrimaryExpression", "new A()", []);
+    InstanceCreationExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "new A()", []);
     JUnitTestCase.assertNotNull(expression);
   }
   void test_parsePrimaryExpression_null() {
-    NullLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "null", []);
+    NullLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "null", []);
     JUnitTestCase.assertNotNull(literal.literal);
   }
   void test_parsePrimaryExpression_parenthesized() {
-    ParenthesizedExpression expression = ParserTestCase.parse4("parsePrimaryExpression", "()", []);
+    ParenthesizedExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "()", []);
     JUnitTestCase.assertNotNull(expression);
   }
   void test_parsePrimaryExpression_string() {
-    SimpleStringLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "\"string\"", []);
+    SimpleStringLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "\"string\"", []);
     JUnitTestCase.assertFalse(literal.isMultiline());
     JUnitTestCase.assertEquals("string", literal.value);
   }
   void test_parsePrimaryExpression_super() {
-    PropertyAccess propertyAccess = ParserTestCase.parse4("parsePrimaryExpression", "super.x", []);
+    PropertyAccess propertyAccess = ParserTestCase.parse5("parsePrimaryExpression", "super.x", []);
     JUnitTestCase.assertTrue(propertyAccess.target is SuperExpression);
     JUnitTestCase.assertNotNull(propertyAccess.operator);
     JUnitTestCase.assertEquals(TokenType.PERIOD, propertyAccess.operator.type);
     JUnitTestCase.assertNotNull(propertyAccess.propertyName);
   }
   void test_parsePrimaryExpression_this() {
-    ThisExpression expression = ParserTestCase.parse4("parsePrimaryExpression", "this", []);
+    ThisExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "this", []);
     JUnitTestCase.assertNotNull(expression.keyword);
   }
   void test_parsePrimaryExpression_true() {
-    BooleanLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "true", []);
+    BooleanLiteral literal = ParserTestCase.parse5("parsePrimaryExpression", "true", []);
     JUnitTestCase.assertNotNull(literal.literal);
     JUnitTestCase.assertTrue(literal.value);
   }
@@ -3689,78 +3689,78 @@
     JUnitTestCase.assertNotNull(new Parser(null, null));
   }
   void test_parseRedirectingConstructorInvocation_named() {
-    RedirectingConstructorInvocation invocation = ParserTestCase.parse4("parseRedirectingConstructorInvocation", "this.a()", []);
+    RedirectingConstructorInvocation invocation = ParserTestCase.parse5("parseRedirectingConstructorInvocation", "this.a()", []);
     JUnitTestCase.assertNotNull(invocation.argumentList);
     JUnitTestCase.assertNotNull(invocation.constructorName);
     JUnitTestCase.assertNotNull(invocation.keyword);
     JUnitTestCase.assertNotNull(invocation.period);
   }
   void test_parseRedirectingConstructorInvocation_unnamed() {
-    RedirectingConstructorInvocation invocation = ParserTestCase.parse4("parseRedirectingConstructorInvocation", "this()", []);
+    RedirectingConstructorInvocation invocation = ParserTestCase.parse5("parseRedirectingConstructorInvocation", "this()", []);
     JUnitTestCase.assertNotNull(invocation.argumentList);
     JUnitTestCase.assertNull(invocation.constructorName);
     JUnitTestCase.assertNotNull(invocation.keyword);
     JUnitTestCase.assertNull(invocation.period);
   }
   void test_parseRelationalExpression_as() {
-    AsExpression expression = ParserTestCase.parse4("parseRelationalExpression", "x as Y", []);
+    AsExpression expression = ParserTestCase.parse5("parseRelationalExpression", "x as Y", []);
     JUnitTestCase.assertNotNull(expression.expression);
     JUnitTestCase.assertNotNull(expression.asOperator);
     JUnitTestCase.assertNotNull(expression.type);
   }
   void test_parseRelationalExpression_is() {
-    IsExpression expression = ParserTestCase.parse4("parseRelationalExpression", "x is y", []);
+    IsExpression expression = ParserTestCase.parse5("parseRelationalExpression", "x is y", []);
     JUnitTestCase.assertNotNull(expression.expression);
     JUnitTestCase.assertNotNull(expression.isOperator);
     JUnitTestCase.assertNull(expression.notOperator);
     JUnitTestCase.assertNotNull(expression.type);
   }
   void test_parseRelationalExpression_isNot() {
-    IsExpression expression = ParserTestCase.parse4("parseRelationalExpression", "x is! y", []);
+    IsExpression expression = ParserTestCase.parse5("parseRelationalExpression", "x is! y", []);
     JUnitTestCase.assertNotNull(expression.expression);
     JUnitTestCase.assertNotNull(expression.isOperator);
     JUnitTestCase.assertNotNull(expression.notOperator);
     JUnitTestCase.assertNotNull(expression.type);
   }
   void test_parseRelationalExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parse4("parseRelationalExpression", "x < y", []);
+    BinaryExpression expression = ParserTestCase.parse5("parseRelationalExpression", "x < y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.LT, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseRelationalExpression_super() {
-    BinaryExpression expression = ParserTestCase.parse4("parseRelationalExpression", "super < y", []);
+    BinaryExpression expression = ParserTestCase.parse5("parseRelationalExpression", "super < y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.LT, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseReturnStatement_noValue() {
-    ReturnStatement statement = ParserTestCase.parse4("parseReturnStatement", "return;", []);
+    ReturnStatement statement = ParserTestCase.parse5("parseReturnStatement", "return;", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNull(statement.expression);
     JUnitTestCase.assertNotNull(statement.semicolon);
   }
   void test_parseReturnStatement_value() {
-    ReturnStatement statement = ParserTestCase.parse4("parseReturnStatement", "return x;", []);
+    ReturnStatement statement = ParserTestCase.parse5("parseReturnStatement", "return x;", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.expression);
     JUnitTestCase.assertNotNull(statement.semicolon);
   }
   void test_parseReturnType_nonVoid() {
-    TypeName typeName = ParserTestCase.parse4("parseReturnType", "A<B>", []);
+    TypeName typeName = ParserTestCase.parse5("parseReturnType", "A<B>", []);
     JUnitTestCase.assertNotNull(typeName.name);
     JUnitTestCase.assertNotNull(typeName.typeArguments);
   }
   void test_parseReturnType_void() {
-    TypeName typeName = ParserTestCase.parse4("parseReturnType", "void", []);
+    TypeName typeName = ParserTestCase.parse5("parseReturnType", "void", []);
     JUnitTestCase.assertNotNull(typeName.name);
     JUnitTestCase.assertNull(typeName.typeArguments);
   }
   void test_parseSetter_nonStatic() {
     Comment comment = Comment.createDocumentationComment(new List<Token>.fixedLength(0));
-    TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
+    TypeName returnType = new TypeName.full(new SimpleIdentifier.full(null), null);
     MethodDeclaration method = ParserTestCase.parse("parseSetter", <Object> [commentAndMetadata(comment, []), null, null, returnType], "set a(var x);");
     JUnitTestCase.assertNotNull(method.body);
     JUnitTestCase.assertEquals(comment, method.documentationComment);
@@ -3775,7 +3775,7 @@
   void test_parseSetter_static() {
     Comment comment = Comment.createDocumentationComment(new List<Token>.fixedLength(0));
     Token staticKeyword = TokenFactory.token(Keyword.STATIC);
-    TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
+    TypeName returnType = new TypeName.full(new SimpleIdentifier.full(null), null);
     MethodDeclaration method = ParserTestCase.parse("parseSetter", <Object> [commentAndMetadata(comment, []), null, staticKeyword, returnType], "set a(var x) {}");
     JUnitTestCase.assertNotNull(method.body);
     JUnitTestCase.assertEquals(comment, method.documentationComment);
@@ -3788,14 +3788,14 @@
     JUnitTestCase.assertEquals(returnType, method.returnType);
   }
   void test_parseShiftExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parse4("parseShiftExpression", "x << y", []);
+    BinaryExpression expression = ParserTestCase.parse5("parseShiftExpression", "x << y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.LT_LT, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.rightOperand);
   }
   void test_parseShiftExpression_super() {
-    BinaryExpression expression = ParserTestCase.parse4("parseShiftExpression", "super << y", []);
+    BinaryExpression expression = ParserTestCase.parse5("parseShiftExpression", "super << y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.LT_LT, expression.operator.type);
@@ -3803,32 +3803,32 @@
   }
   void test_parseSimpleIdentifier_builtInIdentifier() {
     String lexeme = "as";
-    SimpleIdentifier identifier = ParserTestCase.parse4("parseSimpleIdentifier", lexeme, []);
+    SimpleIdentifier identifier = ParserTestCase.parse5("parseSimpleIdentifier", lexeme, []);
     JUnitTestCase.assertNotNull(identifier.token);
     JUnitTestCase.assertEquals(lexeme, identifier.name);
   }
   void test_parseSimpleIdentifier_normalIdentifier() {
     String lexeme = "foo";
-    SimpleIdentifier identifier = ParserTestCase.parse4("parseSimpleIdentifier", lexeme, []);
+    SimpleIdentifier identifier = ParserTestCase.parse5("parseSimpleIdentifier", lexeme, []);
     JUnitTestCase.assertNotNull(identifier.token);
     JUnitTestCase.assertEquals(lexeme, identifier.name);
   }
   void test_parseSimpleIdentifier1_normalIdentifier() {
   }
   void test_parseStatement_functionDeclaration() {
-    FunctionDeclarationStatement statement = ParserTestCase.parse4("parseStatement", "int f(a, b) {};", []);
+    FunctionDeclarationStatement statement = ParserTestCase.parse5("parseStatement", "int f(a, b) {};", []);
     JUnitTestCase.assertNotNull(statement.functionDeclaration);
   }
   void test_parseStatement_mulipleLabels() {
-    LabeledStatement statement = ParserTestCase.parse4("parseStatement", "l: m: return x;", []);
+    LabeledStatement statement = ParserTestCase.parse5("parseStatement", "l: m: return x;", []);
     EngineTestCase.assertSize(2, statement.labels);
     JUnitTestCase.assertNotNull(statement.statement);
   }
   void test_parseStatement_noLabels() {
-    ParserTestCase.parse4("parseStatement", "return x;", []);
+    ParserTestCase.parse5("parseStatement", "return x;", []);
   }
   void test_parseStatement_singleLabel() {
-    LabeledStatement statement = ParserTestCase.parse4("parseStatement", "l: return x;", []);
+    LabeledStatement statement = ParserTestCase.parse5("parseStatement", "l: return x;", []);
     EngineTestCase.assertSize(1, statement.labels);
     JUnitTestCase.assertNotNull(statement.statement);
   }
@@ -3841,16 +3841,16 @@
     EngineTestCase.assertSize(1, statements);
   }
   void test_parseStringLiteral_adjacent() {
-    AdjacentStrings literal = ParserTestCase.parse4("parseStringLiteral", "'a' 'b'", []);
+    AdjacentStrings literal = ParserTestCase.parse5("parseStringLiteral", "'a' 'b'", []);
     NodeList<StringLiteral> strings2 = literal.strings;
     EngineTestCase.assertSize(2, strings2);
     StringLiteral firstString = strings2[0];
     StringLiteral secondString = strings2[1];
-    JUnitTestCase.assertEquals("a", (firstString as SimpleStringLiteral).value);
-    JUnitTestCase.assertEquals("b", (secondString as SimpleStringLiteral).value);
+    JUnitTestCase.assertEquals("a", ((firstString as SimpleStringLiteral)).value);
+    JUnitTestCase.assertEquals("b", ((secondString as SimpleStringLiteral)).value);
   }
   void test_parseStringLiteral_interpolated() {
-    StringInterpolation literal = ParserTestCase.parse4("parseStringLiteral", "'a \${b} c \$this d'", []);
+    StringInterpolation literal = ParserTestCase.parse5("parseStringLiteral", "'a \${b} c \$this d'", []);
     NodeList<InterpolationElement> elements2 = literal.elements;
     EngineTestCase.assertSize(5, elements2);
     JUnitTestCase.assertTrue(elements2[0] is InterpolationString);
@@ -3860,26 +3860,26 @@
     JUnitTestCase.assertTrue(elements2[4] is InterpolationString);
   }
   void test_parseStringLiteral_single() {
-    SimpleStringLiteral literal = ParserTestCase.parse4("parseStringLiteral", "'a'", []);
+    SimpleStringLiteral literal = ParserTestCase.parse5("parseStringLiteral", "'a'", []);
     JUnitTestCase.assertNotNull(literal.literal);
     JUnitTestCase.assertEquals("a", literal.value);
   }
   void test_parseSuperConstructorInvocation_named() {
-    SuperConstructorInvocation invocation = ParserTestCase.parse4("parseSuperConstructorInvocation", "super.a()", []);
+    SuperConstructorInvocation invocation = ParserTestCase.parse5("parseSuperConstructorInvocation", "super.a()", []);
     JUnitTestCase.assertNotNull(invocation.argumentList);
     JUnitTestCase.assertNotNull(invocation.constructorName);
     JUnitTestCase.assertNotNull(invocation.keyword);
     JUnitTestCase.assertNotNull(invocation.period);
   }
   void test_parseSuperConstructorInvocation_unnamed() {
-    SuperConstructorInvocation invocation = ParserTestCase.parse4("parseSuperConstructorInvocation", "super()", []);
+    SuperConstructorInvocation invocation = ParserTestCase.parse5("parseSuperConstructorInvocation", "super()", []);
     JUnitTestCase.assertNotNull(invocation.argumentList);
     JUnitTestCase.assertNull(invocation.constructorName);
     JUnitTestCase.assertNotNull(invocation.keyword);
     JUnitTestCase.assertNull(invocation.period);
   }
   void test_parseSwitchStatement_case() {
-    SwitchStatement statement = ParserTestCase.parse4("parseSwitchStatement", "switch (a) {case 1: return 'I';}", []);
+    SwitchStatement statement = ParserTestCase.parse5("parseSwitchStatement", "switch (a) {case 1: return 'I';}", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.expression);
@@ -3889,7 +3889,7 @@
     JUnitTestCase.assertNotNull(statement.rightBracket);
   }
   void test_parseSwitchStatement_empty() {
-    SwitchStatement statement = ParserTestCase.parse4("parseSwitchStatement", "switch (a) {}", []);
+    SwitchStatement statement = ParserTestCase.parse5("parseSwitchStatement", "switch (a) {}", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.expression);
@@ -3899,7 +3899,7 @@
     JUnitTestCase.assertNotNull(statement.rightBracket);
   }
   void test_parseSwitchStatement_labeledCase() {
-    SwitchStatement statement = ParserTestCase.parse4("parseSwitchStatement", "switch (a) {l1: l2: l3: case(1):}", []);
+    SwitchStatement statement = ParserTestCase.parse5("parseSwitchStatement", "switch (a) {l1: l2: l3: case(1):}", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.expression);
@@ -3910,7 +3910,7 @@
     JUnitTestCase.assertNotNull(statement.rightBracket);
   }
   void test_parseSwitchStatement_labeledStatementInCase() {
-    SwitchStatement statement = ParserTestCase.parse4("parseSwitchStatement", "switch (a) {case 0: f(); l1: g(); break;}", []);
+    SwitchStatement statement = ParserTestCase.parse5("parseSwitchStatement", "switch (a) {case 0: f(); l1: g(); break;}", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.expression);
@@ -3921,27 +3921,27 @@
     JUnitTestCase.assertNotNull(statement.rightBracket);
   }
   void test_parseThrowExpression_expression() {
-    ThrowExpression statement = ParserTestCase.parse4("parseThrowExpression", "throw x;", []);
+    ThrowExpression statement = ParserTestCase.parse5("parseThrowExpression", "throw x;", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseThrowExpression_noExpression() {
-    ThrowExpression statement = ParserTestCase.parse4("parseThrowExpression", "throw;", []);
+    ThrowExpression statement = ParserTestCase.parse5("parseThrowExpression", "throw;", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNull(statement.expression);
   }
   void test_parseThrowExpressionWithoutCascade_expression() {
-    ThrowExpression statement = ParserTestCase.parse4("parseThrowExpressionWithoutCascade", "throw x;", []);
+    ThrowExpression statement = ParserTestCase.parse5("parseThrowExpressionWithoutCascade", "throw x;", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.expression);
   }
   void test_parseThrowExpressionWithoutCascade_noExpression() {
-    ThrowExpression statement = ParserTestCase.parse4("parseThrowExpressionWithoutCascade", "throw;", []);
+    ThrowExpression statement = ParserTestCase.parse5("parseThrowExpressionWithoutCascade", "throw;", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNull(statement.expression);
   }
   void test_parseTryStatement_catch() {
-    TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} catch (e) {}", []);
+    TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} catch (e) {}", []);
     JUnitTestCase.assertNotNull(statement.tryKeyword);
     JUnitTestCase.assertNotNull(statement.body);
     NodeList<CatchClause> catchClauses2 = statement.catchClauses;
@@ -3958,7 +3958,7 @@
     JUnitTestCase.assertNull(statement.finallyClause);
   }
   void test_parseTryStatement_catch_finally() {
-    TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} catch (e, s) {} finally {}", []);
+    TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} catch (e, s) {} finally {}", []);
     JUnitTestCase.assertNotNull(statement.tryKeyword);
     JUnitTestCase.assertNotNull(statement.body);
     NodeList<CatchClause> catchClauses3 = statement.catchClauses;
@@ -3975,7 +3975,7 @@
     JUnitTestCase.assertNotNull(statement.finallyClause);
   }
   void test_parseTryStatement_finally() {
-    TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} finally {}", []);
+    TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} finally {}", []);
     JUnitTestCase.assertNotNull(statement.tryKeyword);
     JUnitTestCase.assertNotNull(statement.body);
     EngineTestCase.assertSize(0, statement.catchClauses);
@@ -3983,7 +3983,7 @@
     JUnitTestCase.assertNotNull(statement.finallyClause);
   }
   void test_parseTryStatement_multiple() {
-    TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} on NPE catch (e) {} on Error {} catch (e) {}", []);
+    TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} on NPE catch (e) {} on Error {} catch (e) {}", []);
     JUnitTestCase.assertNotNull(statement.tryKeyword);
     JUnitTestCase.assertNotNull(statement.body);
     EngineTestCase.assertSize(3, statement.catchClauses);
@@ -3991,7 +3991,7 @@
     JUnitTestCase.assertNull(statement.finallyClause);
   }
   void test_parseTryStatement_on() {
-    TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} on Error {}", []);
+    TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} on Error {}", []);
     JUnitTestCase.assertNotNull(statement.tryKeyword);
     JUnitTestCase.assertNotNull(statement.body);
     NodeList<CatchClause> catchClauses4 = statement.catchClauses;
@@ -4008,7 +4008,7 @@
     JUnitTestCase.assertNull(statement.finallyClause);
   }
   void test_parseTryStatement_on_catch() {
-    TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} on Error catch (e, s) {}", []);
+    TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} on Error catch (e, s) {}", []);
     JUnitTestCase.assertNotNull(statement.tryKeyword);
     JUnitTestCase.assertNotNull(statement.body);
     NodeList<CatchClause> catchClauses5 = statement.catchClauses;
@@ -4025,7 +4025,7 @@
     JUnitTestCase.assertNull(statement.finallyClause);
   }
   void test_parseTryStatement_on_catch_finally() {
-    TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} on Error catch (e, s) {} finally {}", []);
+    TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {} on Error catch (e, s) {} finally {}", []);
     JUnitTestCase.assertNotNull(statement.tryKeyword);
     JUnitTestCase.assertNotNull(statement.body);
     NodeList<CatchClause> catchClauses6 = statement.catchClauses;
@@ -4096,13 +4096,13 @@
     JUnitTestCase.assertNull(typeAlias.typeParameters);
   }
   void test_parseTypeArgumentList_multiple() {
-    TypeArgumentList argumentList = ParserTestCase.parse4("parseTypeArgumentList", "<int, int, int>", []);
+    TypeArgumentList argumentList = ParserTestCase.parse5("parseTypeArgumentList", "<int, int, int>", []);
     JUnitTestCase.assertNotNull(argumentList.leftBracket);
     EngineTestCase.assertSize(3, argumentList.arguments);
     JUnitTestCase.assertNotNull(argumentList.rightBracket);
   }
   void test_parseTypeArgumentList_nested() {
-    TypeArgumentList argumentList = ParserTestCase.parse4("parseTypeArgumentList", "<A<B>>", []);
+    TypeArgumentList argumentList = ParserTestCase.parse5("parseTypeArgumentList", "<A<B>>", []);
     JUnitTestCase.assertNotNull(argumentList.leftBracket);
     EngineTestCase.assertSize(1, argumentList.arguments);
     TypeName argument = argumentList.arguments[0];
@@ -4113,179 +4113,179 @@
     JUnitTestCase.assertNotNull(argumentList.rightBracket);
   }
   void test_parseTypeArgumentList_single() {
-    TypeArgumentList argumentList = ParserTestCase.parse4("parseTypeArgumentList", "<int>", []);
+    TypeArgumentList argumentList = ParserTestCase.parse5("parseTypeArgumentList", "<int>", []);
     JUnitTestCase.assertNotNull(argumentList.leftBracket);
     EngineTestCase.assertSize(1, argumentList.arguments);
     JUnitTestCase.assertNotNull(argumentList.rightBracket);
   }
   void test_parseTypeName_parameterized() {
-    TypeName typeName = ParserTestCase.parse4("parseTypeName", "List<int>", []);
+    TypeName typeName = ParserTestCase.parse5("parseTypeName", "List<int>", []);
     JUnitTestCase.assertNotNull(typeName.name);
     JUnitTestCase.assertNotNull(typeName.typeArguments);
   }
   void test_parseTypeName_simple() {
-    TypeName typeName = ParserTestCase.parse4("parseTypeName", "int", []);
+    TypeName typeName = ParserTestCase.parse5("parseTypeName", "int", []);
     JUnitTestCase.assertNotNull(typeName.name);
     JUnitTestCase.assertNull(typeName.typeArguments);
   }
   void test_parseTypeParameter_bounded() {
-    TypeParameter parameter = ParserTestCase.parse4("parseTypeParameter", "A extends B", []);
+    TypeParameter parameter = ParserTestCase.parse5("parseTypeParameter", "A extends B", []);
     JUnitTestCase.assertNotNull(parameter.bound);
     JUnitTestCase.assertNotNull(parameter.keyword);
     JUnitTestCase.assertNotNull(parameter.name);
   }
   void test_parseTypeParameter_simple() {
-    TypeParameter parameter = ParserTestCase.parse4("parseTypeParameter", "A", []);
+    TypeParameter parameter = ParserTestCase.parse5("parseTypeParameter", "A", []);
     JUnitTestCase.assertNull(parameter.bound);
     JUnitTestCase.assertNull(parameter.keyword);
     JUnitTestCase.assertNotNull(parameter.name);
   }
   void test_parseTypeParameterList_multiple() {
-    TypeParameterList parameterList = ParserTestCase.parse4("parseTypeParameterList", "<A, B extends C, D>", []);
+    TypeParameterList parameterList = ParserTestCase.parse5("parseTypeParameterList", "<A, B extends C, D>", []);
     JUnitTestCase.assertNotNull(parameterList.leftBracket);
     JUnitTestCase.assertNotNull(parameterList.rightBracket);
     EngineTestCase.assertSize(3, parameterList.typeParameters);
   }
   void test_parseTypeParameterList_parameterizedWithTrailingEquals() {
-    TypeParameterList parameterList = ParserTestCase.parse4("parseTypeParameterList", "<A extends B<E>>=", []);
+    TypeParameterList parameterList = ParserTestCase.parse5("parseTypeParameterList", "<A extends B<E>>=", []);
     JUnitTestCase.assertNotNull(parameterList.leftBracket);
     JUnitTestCase.assertNotNull(parameterList.rightBracket);
     EngineTestCase.assertSize(1, parameterList.typeParameters);
   }
   void test_parseTypeParameterList_single() {
-    TypeParameterList parameterList = ParserTestCase.parse4("parseTypeParameterList", "<A>", []);
+    TypeParameterList parameterList = ParserTestCase.parse5("parseTypeParameterList", "<A>", []);
     JUnitTestCase.assertNotNull(parameterList.leftBracket);
     JUnitTestCase.assertNotNull(parameterList.rightBracket);
     EngineTestCase.assertSize(1, parameterList.typeParameters);
   }
   void test_parseTypeParameterList_withTrailingEquals() {
-    TypeParameterList parameterList = ParserTestCase.parse4("parseTypeParameterList", "<A>=", []);
+    TypeParameterList parameterList = ParserTestCase.parse5("parseTypeParameterList", "<A>=", []);
     JUnitTestCase.assertNotNull(parameterList.leftBracket);
     JUnitTestCase.assertNotNull(parameterList.rightBracket);
     EngineTestCase.assertSize(1, parameterList.typeParameters);
   }
   void test_parseUnaryExpression_decrement_normal() {
-    PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "--x", []);
+    PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "--x", []);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.MINUS_MINUS, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.operand);
   }
   void test_parseUnaryExpression_decrement_super() {
-    PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "--super", []);
+    PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "--super", []);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.MINUS, expression.operator.type);
     Expression innerExpression = expression.operand;
     JUnitTestCase.assertNotNull(innerExpression);
     JUnitTestCase.assertTrue(innerExpression is PrefixExpression);
-    PrefixExpression operand = innerExpression as PrefixExpression;
+    PrefixExpression operand = (innerExpression as PrefixExpression);
     JUnitTestCase.assertNotNull(operand.operator);
     JUnitTestCase.assertEquals(TokenType.MINUS, operand.operator.type);
     JUnitTestCase.assertNotNull(operand.operand);
   }
   void test_parseUnaryExpression_increment_normal() {
-    PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "++x", []);
+    PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "++x", []);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.PLUS_PLUS, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.operand);
   }
   void test_parseUnaryExpression_minus_normal() {
-    PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "-x", []);
+    PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "-x", []);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.MINUS, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.operand);
   }
   void test_parseUnaryExpression_minus_super() {
-    PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "-super", []);
+    PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "-super", []);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.MINUS, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.operand);
   }
   void test_parseUnaryExpression_not_normal() {
-    PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "!x", []);
+    PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "!x", []);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.BANG, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.operand);
   }
   void test_parseUnaryExpression_not_super() {
-    PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "!super", []);
+    PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "!super", []);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.BANG, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.operand);
   }
   void test_parseUnaryExpression_tilda_normal() {
-    PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "~x", []);
+    PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "~x", []);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.TILDE, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.operand);
   }
   void test_parseUnaryExpression_tilda_super() {
-    PrefixExpression expression = ParserTestCase.parse4("parseUnaryExpression", "~super", []);
+    PrefixExpression expression = ParserTestCase.parse5("parseUnaryExpression", "~super", []);
     JUnitTestCase.assertNotNull(expression.operator);
     JUnitTestCase.assertEquals(TokenType.TILDE, expression.operator.type);
     JUnitTestCase.assertNotNull(expression.operand);
   }
   void test_parseVariableDeclaration_equals() {
-    VariableDeclaration declaration = ParserTestCase.parse4("parseVariableDeclaration", "a = b", []);
+    VariableDeclaration declaration = ParserTestCase.parse5("parseVariableDeclaration", "a = b", []);
     JUnitTestCase.assertNotNull(declaration.name);
     JUnitTestCase.assertNotNull(declaration.equals);
     JUnitTestCase.assertNotNull(declaration.initializer);
   }
   void test_parseVariableDeclaration_noEquals() {
-    VariableDeclaration declaration = ParserTestCase.parse4("parseVariableDeclaration", "a", []);
+    VariableDeclaration declaration = ParserTestCase.parse5("parseVariableDeclaration", "a", []);
     JUnitTestCase.assertNotNull(declaration.name);
     JUnitTestCase.assertNull(declaration.equals);
     JUnitTestCase.assertNull(declaration.initializer);
   }
   void test_parseVariableDeclarationList_const_noType() {
-    VariableDeclarationList declarationList = ParserTestCase.parse4("parseVariableDeclarationList", "const a", []);
+    VariableDeclarationList declarationList = ParserTestCase.parse5("parseVariableDeclarationList", "const a", []);
     JUnitTestCase.assertNotNull(declarationList.keyword);
     JUnitTestCase.assertNull(declarationList.type);
     EngineTestCase.assertSize(1, declarationList.variables);
   }
   void test_parseVariableDeclarationList_const_type() {
-    VariableDeclarationList declarationList = ParserTestCase.parse4("parseVariableDeclarationList", "const A a", []);
+    VariableDeclarationList declarationList = ParserTestCase.parse5("parseVariableDeclarationList", "const A a", []);
     JUnitTestCase.assertNotNull(declarationList.keyword);
     JUnitTestCase.assertNotNull(declarationList.type);
     EngineTestCase.assertSize(1, declarationList.variables);
   }
   void test_parseVariableDeclarationList_final_noType() {
-    VariableDeclarationList declarationList = ParserTestCase.parse4("parseVariableDeclarationList", "final a", []);
+    VariableDeclarationList declarationList = ParserTestCase.parse5("parseVariableDeclarationList", "final a", []);
     JUnitTestCase.assertNotNull(declarationList.keyword);
     JUnitTestCase.assertNull(declarationList.type);
     EngineTestCase.assertSize(1, declarationList.variables);
   }
   void test_parseVariableDeclarationList_final_type() {
-    VariableDeclarationList declarationList = ParserTestCase.parse4("parseVariableDeclarationList", "final A a", []);
+    VariableDeclarationList declarationList = ParserTestCase.parse5("parseVariableDeclarationList", "final A a", []);
     JUnitTestCase.assertNotNull(declarationList.keyword);
     JUnitTestCase.assertNotNull(declarationList.type);
     EngineTestCase.assertSize(1, declarationList.variables);
   }
   void test_parseVariableDeclarationList_type_multiple() {
-    VariableDeclarationList declarationList = ParserTestCase.parse4("parseVariableDeclarationList", "A a, b, c", []);
+    VariableDeclarationList declarationList = ParserTestCase.parse5("parseVariableDeclarationList", "A a, b, c", []);
     JUnitTestCase.assertNull(declarationList.keyword);
     JUnitTestCase.assertNotNull(declarationList.type);
     EngineTestCase.assertSize(3, declarationList.variables);
   }
   void test_parseVariableDeclarationList_type_single() {
-    VariableDeclarationList declarationList = ParserTestCase.parse4("parseVariableDeclarationList", "A a", []);
+    VariableDeclarationList declarationList = ParserTestCase.parse5("parseVariableDeclarationList", "A a", []);
     JUnitTestCase.assertNull(declarationList.keyword);
     JUnitTestCase.assertNotNull(declarationList.type);
     EngineTestCase.assertSize(1, declarationList.variables);
   }
   void test_parseVariableDeclarationList_var_multiple() {
-    VariableDeclarationList declarationList = ParserTestCase.parse4("parseVariableDeclarationList", "var a, b, c", []);
+    VariableDeclarationList declarationList = ParserTestCase.parse5("parseVariableDeclarationList", "var a, b, c", []);
     JUnitTestCase.assertNotNull(declarationList.keyword);
     JUnitTestCase.assertNull(declarationList.type);
     EngineTestCase.assertSize(3, declarationList.variables);
   }
   void test_parseVariableDeclarationList_var_single() {
-    VariableDeclarationList declarationList = ParserTestCase.parse4("parseVariableDeclarationList", "var a", []);
+    VariableDeclarationList declarationList = ParserTestCase.parse5("parseVariableDeclarationList", "var a", []);
     JUnitTestCase.assertNotNull(declarationList.keyword);
     JUnitTestCase.assertNull(declarationList.type);
     EngineTestCase.assertSize(1, declarationList.variables);
   }
   void test_parseVariableDeclarationList2_type() {
-    TypeName type = new TypeName(new SimpleIdentifier(null), null);
+    TypeName type = new TypeName.full(new SimpleIdentifier.full(null), null);
     VariableDeclarationList declarationList = ParserTestCase.parse("parseVariableDeclarationList", <Object> [null, type], "a");
     JUnitTestCase.assertNull(declarationList.keyword);
     JUnitTestCase.assertEquals(type, declarationList.type);
@@ -4299,21 +4299,21 @@
     EngineTestCase.assertSize(3, declarationList.variables);
   }
   void test_parseVariableDeclarationStatement_multiple() {
-    VariableDeclarationStatement statement = ParserTestCase.parse4("parseVariableDeclarationStatement", "var x, y, z;", []);
+    VariableDeclarationStatement statement = ParserTestCase.parse5("parseVariableDeclarationStatement", "var x, y, z;", []);
     JUnitTestCase.assertNotNull(statement.semicolon);
     VariableDeclarationList variableList = statement.variables;
     JUnitTestCase.assertNotNull(variableList);
     EngineTestCase.assertSize(3, variableList.variables);
   }
   void test_parseVariableDeclarationStatement_single() {
-    VariableDeclarationStatement statement = ParserTestCase.parse4("parseVariableDeclarationStatement", "var x;", []);
+    VariableDeclarationStatement statement = ParserTestCase.parse5("parseVariableDeclarationStatement", "var x;", []);
     JUnitTestCase.assertNotNull(statement.semicolon);
     VariableDeclarationList variableList = statement.variables;
     JUnitTestCase.assertNotNull(variableList);
     EngineTestCase.assertSize(1, variableList.variables);
   }
   void test_parseWhileStatement() {
-    WhileStatement statement = ParserTestCase.parse4("parseWhileStatement", "while (x) {}", []);
+    WhileStatement statement = ParserTestCase.parse5("parseWhileStatement", "while (x) {}", []);
     JUnitTestCase.assertNotNull(statement.keyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.condition);
@@ -4321,12 +4321,12 @@
     JUnitTestCase.assertNotNull(statement.body);
   }
   void test_parseWithClause_multiple() {
-    WithClause clause = ParserTestCase.parse4("parseWithClause", "with A, B, C", []);
+    WithClause clause = ParserTestCase.parse5("parseWithClause", "with A, B, C", []);
     JUnitTestCase.assertNotNull(clause.withKeyword);
     EngineTestCase.assertSize(3, clause.mixinTypes);
   }
   void test_parseWithClause_single() {
-    WithClause clause = ParserTestCase.parse4("parseWithClause", "with M", []);
+    WithClause clause = ParserTestCase.parse5("parseWithClause", "with M", []);
     JUnitTestCase.assertNotNull(clause.withKeyword);
     EngineTestCase.assertSize(1, clause.mixinTypes);
   }
@@ -4426,9 +4426,9 @@
    * @throws Exception if the method could not be invoked or throws an exception
    */
   String computeStringValue(String lexeme) {
-    AnalysisErrorListener listener = new AnalysisErrorListener_4();
+    AnalysisErrorListener listener = new AnalysisErrorListener_10();
     Parser parser = new Parser(null, listener);
-    return invokeParserMethodImpl(parser, "computeStringValue", <Object> [lexeme], null) as String;
+    return (invokeParserMethodImpl(parser, "computeStringValue", <Object> [lexeme], null) as String);
   }
   /**
    * Invoke the method {@link Parser#createSyntheticIdentifier()} with the parser set to the token
@@ -4475,7 +4475,7 @@
     StringScanner scanner = new StringScanner(null, source, listener);
     Token tokenStream = scanner.tokenize();
     Parser parser = new Parser(null, listener);
-    return invokeParserMethodImpl(parser, "isFunctionExpression", <Object> [tokenStream], tokenStream) as bool;
+    return (invokeParserMethodImpl(parser, "isFunctionExpression", <Object> [tokenStream], tokenStream) as bool);
   }
   /**
    * Invoke the method {@link Parser#isInitializedVariableDeclaration()} with the parser set to the
@@ -4513,7 +4513,7 @@
     StringScanner scanner = new StringScanner(null, source, listener);
     Token tokenStream = scanner.tokenize();
     Parser parser = new Parser(null, listener);
-    return invokeParserMethodImpl(parser, methodName, <Object> [tokenStream], tokenStream) as Token;
+    return (invokeParserMethodImpl(parser, methodName, <Object> [tokenStream], tokenStream) as Token);
   }
   static dartSuite() {
     _ut.group('SimpleParserTest', () {
@@ -6484,7 +6484,7 @@
     });
   }
 }
-class AnalysisErrorListener_4 implements AnalysisErrorListener {
+class AnalysisErrorListener_10 implements AnalysisErrorListener {
   void onError(AnalysisError event) {
     JUnitTestCase.fail("Unexpected compilation error: ${event.message} (${event.offset}, ${event.length})");
   }
@@ -6611,11 +6611,11 @@
   void test_conditionalExpression_precedence_argumentDefinitionTest_not() {
     ConditionalExpression conditional = ParserTestCase.parseExpression("!?a?!?b:!?c", []);
     EngineTestCase.assertInstanceOf(PrefixExpression, conditional.condition);
-    EngineTestCase.assertInstanceOf(ArgumentDefinitionTest, (conditional.condition as PrefixExpression).operand);
+    EngineTestCase.assertInstanceOf(ArgumentDefinitionTest, ((conditional.condition as PrefixExpression)).operand);
     EngineTestCase.assertInstanceOf(PrefixExpression, conditional.thenExpression);
-    EngineTestCase.assertInstanceOf(ArgumentDefinitionTest, (conditional.thenExpression as PrefixExpression).operand);
+    EngineTestCase.assertInstanceOf(ArgumentDefinitionTest, ((conditional.thenExpression as PrefixExpression)).operand);
     EngineTestCase.assertInstanceOf(PrefixExpression, conditional.elseExpression);
-    EngineTestCase.assertInstanceOf(ArgumentDefinitionTest, (conditional.elseExpression as PrefixExpression).operand);
+    EngineTestCase.assertInstanceOf(ArgumentDefinitionTest, ((conditional.elseExpression as PrefixExpression)).operand);
   }
   void test_conditionalExpression_precedence_logicalOrExpression() {
     ConditionalExpression expression = ParserTestCase.parseExpression("a | b ? y : z", []);
@@ -6902,517 +6902,517 @@
  */
 class ErrorParserTest extends ParserTestCase {
   void fail_expectedListOrMapLiteral() {
-    TypedLiteral literal = ParserTestCase.parse3("parseListOrMapLiteral", <Object> [null], "1", [ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL]);
+    TypedLiteral literal = ParserTestCase.parse4("parseListOrMapLiteral", <Object> [null], "1", [ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL]);
     JUnitTestCase.assertTrue(literal.isSynthetic());
   }
   void fail_illegalAssignmentToNonAssignable_superAssigned() {
-    ParserTestCase.parse4("parseExpression", "super = x;", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
+    ParserTestCase.parse5("parseExpression", "super = x;", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
   }
   void fail_invalidCommentReference__new_nonIdentifier() {
-    ParserTestCase.parse3("parseCommentReference", <Object> ["new 42", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
+    ParserTestCase.parse4("parseCommentReference", <Object> ["new 42", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
   }
   void fail_invalidCommentReference__new_tooMuch() {
-    ParserTestCase.parse3("parseCommentReference", <Object> ["new a.b.c.d", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
+    ParserTestCase.parse4("parseCommentReference", <Object> ["new a.b.c.d", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
   }
   void fail_invalidCommentReference__nonNew_nonIdentifier() {
-    ParserTestCase.parse3("parseCommentReference", <Object> ["42", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
+    ParserTestCase.parse4("parseCommentReference", <Object> ["42", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
   }
   void fail_invalidCommentReference__nonNew_tooMuch() {
-    ParserTestCase.parse3("parseCommentReference", <Object> ["a.b.c.d", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
+    ParserTestCase.parse4("parseCommentReference", <Object> ["a.b.c.d", 0], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
   }
   void fail_missingFunctionParameters_local_nonVoid_block() {
-    ParserTestCase.parse4("parseStatement", "int f { return x;}", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
+    ParserTestCase.parse5("parseStatement", "int f { return x;}", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
   }
   void fail_missingFunctionParameters_local_nonVoid_expression() {
-    ParserTestCase.parse4("parseStatement", "int f => x;", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
+    ParserTestCase.parse5("parseStatement", "int f => x;", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
   }
   void fail_unexpectedToken_invalidPostfixExpression() {
-    ParserTestCase.parse4("parseExpression", "f()++", [ParserErrorCode.UNEXPECTED_TOKEN]);
+    ParserTestCase.parse5("parseExpression", "f()++", [ParserErrorCode.UNEXPECTED_TOKEN]);
   }
   void fail_voidVariable_initializer() {
-    ParserTestCase.parse4("parseStatement", "void x = 0;", [ParserErrorCode.VOID_VARIABLE]);
+    ParserTestCase.parse5("parseStatement", "void x = 0;", [ParserErrorCode.VOID_VARIABLE]);
   }
   void fail_voidVariable_noInitializer() {
-    ParserTestCase.parse4("parseStatement", "void x;", [ParserErrorCode.VOID_VARIABLE]);
+    ParserTestCase.parse5("parseStatement", "void x;", [ParserErrorCode.VOID_VARIABLE]);
   }
   void test_abstractClassMember_constructor() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "abstract C.c();", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "abstract C.c();", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
   }
   void test_abstractClassMember_field() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "abstract C f;", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "abstract C f;", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
   }
   void test_abstractClassMember_getter() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "abstract get m;", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "abstract get m;", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
   }
   void test_abstractClassMember_method() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "abstract m();", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "abstract m();", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
   }
   void test_abstractClassMember_setter() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "abstract set m(v);", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "abstract set m(v);", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
   }
   void test_abstractTopLevelFunction_function() {
-    ParserTestCase.parse4("parseCompilationUnit", "abstract f(v) {}", [ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION]);
+    ParserTestCase.parse5("parseCompilationUnit", "abstract f(v) {}", [ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION]);
   }
   void test_abstractTopLevelFunction_getter() {
-    ParserTestCase.parse4("parseCompilationUnit", "abstract get m {}", [ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION]);
+    ParserTestCase.parse5("parseCompilationUnit", "abstract get m {}", [ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION]);
   }
   void test_abstractTopLevelFunction_setter() {
-    ParserTestCase.parse4("parseCompilationUnit", "abstract set m(v) {}", [ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION]);
+    ParserTestCase.parse5("parseCompilationUnit", "abstract set m(v) {}", [ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION]);
   }
   void test_abstractTopLevelVariable() {
-    ParserTestCase.parse4("parseCompilationUnit", "abstract C f;", [ParserErrorCode.ABSTRACT_TOP_LEVEL_VARIABLE]);
+    ParserTestCase.parse5("parseCompilationUnit", "abstract C f;", [ParserErrorCode.ABSTRACT_TOP_LEVEL_VARIABLE]);
   }
   void test_abstractTypeDef() {
-    ParserTestCase.parse4("parseCompilationUnit", "abstract typedef F();", [ParserErrorCode.ABSTRACT_TYPEDEF]);
+    ParserTestCase.parse5("parseCompilationUnit", "abstract typedef F();", [ParserErrorCode.ABSTRACT_TYPEDEF]);
   }
   void test_breakOutsideOfLoop_breakInDoStatement() {
-    ParserTestCase.parse4("parseDoStatement", "do {break;} while (x);", []);
+    ParserTestCase.parse5("parseDoStatement", "do {break;} while (x);", []);
   }
   void test_breakOutsideOfLoop_breakInForStatement() {
-    ParserTestCase.parse4("parseForStatement", "for (; x;) {break;}", []);
+    ParserTestCase.parse5("parseForStatement", "for (; x;) {break;}", []);
   }
   void test_breakOutsideOfLoop_breakInIfStatement() {
-    ParserTestCase.parse4("parseIfStatement", "if (x) {break;}", [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]);
+    ParserTestCase.parse5("parseIfStatement", "if (x) {break;}", [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]);
   }
   void test_breakOutsideOfLoop_breakInSwitchStatement() {
-    ParserTestCase.parse4("parseSwitchStatement", "switch (x) {case 1: break;}", []);
+    ParserTestCase.parse5("parseSwitchStatement", "switch (x) {case 1: break;}", []);
   }
   void test_breakOutsideOfLoop_breakInWhileStatement() {
-    ParserTestCase.parse4("parseWhileStatement", "while (x) {break;}", []);
+    ParserTestCase.parse5("parseWhileStatement", "while (x) {break;}", []);
   }
   void test_breakOutsideOfLoop_functionExpression_inALoop() {
-    ParserTestCase.parse4("parseStatement", "for(; x;) {() {break;};}", [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]);
+    ParserTestCase.parse5("parseStatement", "for(; x;) {() {break;};}", [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]);
   }
   void test_breakOutsideOfLoop_functionExpression_withALoop() {
-    ParserTestCase.parse4("parseStatement", "() {for (; x;) {break;}};", []);
+    ParserTestCase.parse5("parseStatement", "() {for (; x;) {break;}};", []);
   }
   void test_builtInIdentifierAsTypeDefName() {
-    ParserTestCase.parse3("parseTypeAlias", <Object> [emptyCommentAndMetadata()], "typedef as();", [ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]);
+    ParserTestCase.parse4("parseTypeAlias", <Object> [emptyCommentAndMetadata()], "typedef as();", [ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]);
   }
   void test_builtInIdentifierAsTypeName() {
-    ParserTestCase.parse3("parseClassDeclaration", <Object> [emptyCommentAndMetadata(), null], "class as {}", [ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME]);
+    ParserTestCase.parse4("parseClassDeclaration", <Object> [emptyCommentAndMetadata(), null], "class as {}", [ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME]);
   }
   void test_builtInIdentifierAsTypeVariableName() {
-    ParserTestCase.parse4("parseTypeParameter", "as", [ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME]);
+    ParserTestCase.parse5("parseTypeParameter", "as", [ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME]);
   }
   void test_constAndFinal() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "const final int x;", [ParserErrorCode.CONST_AND_FINAL]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "const final int x;", [ParserErrorCode.CONST_AND_FINAL]);
   }
   void test_constAndVar() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "const var x;", [ParserErrorCode.CONST_AND_VAR]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "const var x;", [ParserErrorCode.CONST_AND_VAR]);
   }
   void test_constClass() {
-    ParserTestCase.parse4("parseCompilationUnit", "const class C {}", [ParserErrorCode.CONST_CLASS]);
+    ParserTestCase.parse5("parseCompilationUnit", "const class C {}", [ParserErrorCode.CONST_CLASS]);
   }
   void test_constMethod() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "const int m() {}", [ParserErrorCode.CONST_METHOD]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "const int m() {}", [ParserErrorCode.CONST_METHOD]);
   }
   void test_constTypedef() {
-    ParserTestCase.parse4("parseCompilationUnit", "const typedef F();", [ParserErrorCode.CONST_TYPEDEF]);
+    ParserTestCase.parse5("parseCompilationUnit", "const typedef F();", [ParserErrorCode.CONST_TYPEDEF]);
   }
   void test_continueOutsideOfLoop_continueInDoStatement() {
-    ParserTestCase.parse4("parseDoStatement", "do {continue;} while (x);", []);
+    ParserTestCase.parse5("parseDoStatement", "do {continue;} while (x);", []);
   }
   void test_continueOutsideOfLoop_continueInForStatement() {
-    ParserTestCase.parse4("parseForStatement", "for (; x;) {continue;}", []);
+    ParserTestCase.parse5("parseForStatement", "for (; x;) {continue;}", []);
   }
   void test_continueOutsideOfLoop_continueInIfStatement() {
-    ParserTestCase.parse4("parseIfStatement", "if (x) {continue;}", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
+    ParserTestCase.parse5("parseIfStatement", "if (x) {continue;}", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
   }
   void test_continueOutsideOfLoop_continueInSwitchStatement() {
-    ParserTestCase.parse4("parseSwitchStatement", "switch (x) {case 1: continue a;}", []);
+    ParserTestCase.parse5("parseSwitchStatement", "switch (x) {case 1: continue a;}", []);
   }
   void test_continueOutsideOfLoop_continueInWhileStatement() {
-    ParserTestCase.parse4("parseWhileStatement", "while (x) {continue;}", []);
+    ParserTestCase.parse5("parseWhileStatement", "while (x) {continue;}", []);
   }
   void test_continueOutsideOfLoop_functionExpression_inALoop() {
-    ParserTestCase.parse4("parseStatement", "for(; x;) {() {continue;};}", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
+    ParserTestCase.parse5("parseStatement", "for(; x;) {() {continue;};}", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
   }
   void test_continueOutsideOfLoop_functionExpression_withALoop() {
-    ParserTestCase.parse4("parseStatement", "() {for (; x;) {continue;}};", []);
+    ParserTestCase.parse5("parseStatement", "() {for (; x;) {continue;}};", []);
   }
   void test_continueWithoutLabelInCase_error() {
-    ParserTestCase.parse4("parseSwitchStatement", "switch (x) {case 1: continue;}", [ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE]);
+    ParserTestCase.parse5("parseSwitchStatement", "switch (x) {case 1: continue;}", [ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE]);
   }
   void test_continueWithoutLabelInCase_noError() {
-    ParserTestCase.parse4("parseSwitchStatement", "switch (x) {case 1: continue a;}", []);
+    ParserTestCase.parse5("parseSwitchStatement", "switch (x) {case 1: continue a;}", []);
   }
   void test_continueWithoutLabelInCase_noError_switchInLoop() {
-    ParserTestCase.parse4("parseWhileStatement", "while (a) { switch (b) {default: continue;}}", []);
+    ParserTestCase.parse5("parseWhileStatement", "while (a) { switch (b) {default: continue;}}", []);
   }
   void test_directiveAfterDeclaration_classBeforeDirective() {
-    CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "class Foo{} library l;", [ParserErrorCode.DIRECTIVE_AFTER_DECLARATION]);
+    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "class Foo{} library l;", [ParserErrorCode.DIRECTIVE_AFTER_DECLARATION]);
     JUnitTestCase.assertNotNull(unit);
   }
   void test_directiveAfterDeclaration_classBetweenDirectives() {
-    CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "library l;\nclass Foo{}\npart 'a.dart';", [ParserErrorCode.DIRECTIVE_AFTER_DECLARATION]);
+    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "library l;\nclass Foo{}\npart 'a.dart';", [ParserErrorCode.DIRECTIVE_AFTER_DECLARATION]);
     JUnitTestCase.assertNotNull(unit);
   }
   void test_duplicatedModifier_const() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "const const m;", [ParserErrorCode.DUPLICATED_MODIFIER]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "const const m;", [ParserErrorCode.DUPLICATED_MODIFIER]);
   }
   void test_duplicatedModifier_external() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "external external f();", [ParserErrorCode.DUPLICATED_MODIFIER]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external external f();", [ParserErrorCode.DUPLICATED_MODIFIER]);
   }
   void test_duplicatedModifier_factory() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "factory factory C() {}", [ParserErrorCode.DUPLICATED_MODIFIER]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "factory factory C() {}", [ParserErrorCode.DUPLICATED_MODIFIER]);
   }
   void test_duplicatedModifier_final() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "final final m;", [ParserErrorCode.DUPLICATED_MODIFIER]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "final final m;", [ParserErrorCode.DUPLICATED_MODIFIER]);
   }
   void test_duplicatedModifier_static() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "static static m;", [ParserErrorCode.DUPLICATED_MODIFIER]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "static static m;", [ParserErrorCode.DUPLICATED_MODIFIER]);
   }
   void test_duplicatedModifier_var() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "var var m;", [ParserErrorCode.DUPLICATED_MODIFIER]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "var var m;", [ParserErrorCode.DUPLICATED_MODIFIER]);
   }
   void test_duplicateLabelInSwitchStatement() {
-    ParserTestCase.parse4("parseSwitchStatement", "switch (e) {l1: case 0: break; l1: case 1: break;}", [ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT]);
+    ParserTestCase.parse5("parseSwitchStatement", "switch (e) {l1: case 0: break; l1: case 1: break;}", [ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT]);
   }
   void test_expectedCaseOrDefault() {
-    ParserTestCase.parse4("parseSwitchStatement", "switch (e) {break;}", [ParserErrorCode.EXPECTED_CASE_OR_DEFAULT]);
+    ParserTestCase.parse5("parseSwitchStatement", "switch (e) {break;}", [ParserErrorCode.EXPECTED_CASE_OR_DEFAULT]);
   }
   void test_expectedStringLiteral() {
-    StringLiteral expression = ParserTestCase.parse4("parseStringLiteral", "1", [ParserErrorCode.EXPECTED_STRING_LITERAL]);
+    StringLiteral expression = ParserTestCase.parse5("parseStringLiteral", "1", [ParserErrorCode.EXPECTED_STRING_LITERAL]);
     JUnitTestCase.assertTrue(expression.isSynthetic());
   }
   void test_expectedToken_commaMissingInArgumentList() {
-    ParserTestCase.parse4("parseArgumentList", "(x, y z)", [ParserErrorCode.EXPECTED_TOKEN]);
+    ParserTestCase.parse5("parseArgumentList", "(x, y z)", [ParserErrorCode.EXPECTED_TOKEN]);
   }
   void test_expectedToken_semicolonMissingAfterExpression() {
-    ParserTestCase.parse4("parseStatement", "x", [ParserErrorCode.EXPECTED_TOKEN]);
+    ParserTestCase.parse5("parseStatement", "x", [ParserErrorCode.EXPECTED_TOKEN]);
   }
   void test_expectedToken_whileMissingInDoStatement() {
-    ParserTestCase.parse4("parseStatement", "do {} (x);", [ParserErrorCode.EXPECTED_TOKEN]);
+    ParserTestCase.parse5("parseStatement", "do {} (x);", [ParserErrorCode.EXPECTED_TOKEN]);
   }
   void test_exportDirectiveAfterPartDirective() {
-    ParserTestCase.parse4("parseCompilationUnit", "part 'a.dart'; export 'b.dart';", [ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE]);
+    ParserTestCase.parse5("parseCompilationUnit", "part 'a.dart'; export 'b.dart';", [ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE]);
   }
   void test_externalAfterConst() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "const external C();", [ParserErrorCode.EXTERNAL_AFTER_CONST]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "const external C();", [ParserErrorCode.EXTERNAL_AFTER_CONST]);
   }
   void test_externalAfterFactory() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "factory external C();", [ParserErrorCode.EXTERNAL_AFTER_FACTORY]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "factory external C();", [ParserErrorCode.EXTERNAL_AFTER_FACTORY]);
   }
   void test_externalAfterStatic() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "static external int m();", [ParserErrorCode.EXTERNAL_AFTER_STATIC]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "static external int m();", [ParserErrorCode.EXTERNAL_AFTER_STATIC]);
   }
   void test_externalClass() {
-    ParserTestCase.parse4("parseCompilationUnit", "external class C {}", [ParserErrorCode.EXTERNAL_CLASS]);
+    ParserTestCase.parse5("parseCompilationUnit", "external class C {}", [ParserErrorCode.EXTERNAL_CLASS]);
   }
   void test_externalConstructorWithBody_factory() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "external factory C() {}", [ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external factory C() {}", [ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY]);
   }
   void test_externalConstructorWithBody_named() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "external C.c() {}", [ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external C.c() {}", [ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY]);
   }
   void test_externalField_const() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "external const A f;", [ParserErrorCode.EXTERNAL_FIELD]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external const A f;", [ParserErrorCode.EXTERNAL_FIELD]);
   }
   void test_externalField_final() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "external final A f;", [ParserErrorCode.EXTERNAL_FIELD]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external final A f;", [ParserErrorCode.EXTERNAL_FIELD]);
   }
   void test_externalField_static() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "external static A f;", [ParserErrorCode.EXTERNAL_FIELD]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external static A f;", [ParserErrorCode.EXTERNAL_FIELD]);
   }
   void test_externalField_typed() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "external A f;", [ParserErrorCode.EXTERNAL_FIELD]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external A f;", [ParserErrorCode.EXTERNAL_FIELD]);
   }
   void test_externalField_untyped() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "external var f;", [ParserErrorCode.EXTERNAL_FIELD]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external var f;", [ParserErrorCode.EXTERNAL_FIELD]);
   }
   void test_externalGetterWithBody() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "external int get x {}", [ParserErrorCode.EXTERNAL_GETTER_WITH_BODY]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external int get x {}", [ParserErrorCode.EXTERNAL_GETTER_WITH_BODY]);
   }
   void test_externalMethodWithBody() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "external m() {}", [ParserErrorCode.EXTERNAL_METHOD_WITH_BODY]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external m() {}", [ParserErrorCode.EXTERNAL_METHOD_WITH_BODY]);
   }
   void test_externalOperatorWithBody() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "external operator +(int value) {}", [ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external operator +(int value) {}", [ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY]);
   }
   void test_externalSetterWithBody() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "external set x(int value) {}", [ParserErrorCode.EXTERNAL_SETTER_WITH_BODY]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "external set x(int value) {}", [ParserErrorCode.EXTERNAL_SETTER_WITH_BODY]);
   }
   void test_externalTypedef() {
-    ParserTestCase.parse4("parseCompilationUnit", "external typedef F();", [ParserErrorCode.EXTERNAL_TYPEDEF]);
+    ParserTestCase.parse5("parseCompilationUnit", "external typedef F();", [ParserErrorCode.EXTERNAL_TYPEDEF]);
   }
   void test_factoryTopLevelDeclaration_class() {
-    ParserTestCase.parse4("parseCompilationUnit", "factory class C {}", [ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION]);
+    ParserTestCase.parse5("parseCompilationUnit", "factory class C {}", [ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION]);
   }
   void test_factoryTopLevelDeclaration_typedef() {
-    ParserTestCase.parse4("parseCompilationUnit", "factory typedef F();", [ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION]);
+    ParserTestCase.parse5("parseCompilationUnit", "factory typedef F();", [ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION]);
   }
   void test_fieldInitializerOutsideConstructor() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "void m(this.x);", [ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "void m(this.x);", [ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]);
   }
   void test_finalAndVar() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "final var x;", [ParserErrorCode.FINAL_AND_VAR]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "final var x;", [ParserErrorCode.FINAL_AND_VAR]);
   }
   void test_finalClass() {
-    ParserTestCase.parse4("parseCompilationUnit", "final class C {}", [ParserErrorCode.FINAL_CLASS]);
+    ParserTestCase.parse5("parseCompilationUnit", "final class C {}", [ParserErrorCode.FINAL_CLASS]);
   }
   void test_finalConstructor() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "final C() {}", [ParserErrorCode.FINAL_CONSTRUCTOR]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "final C() {}", [ParserErrorCode.FINAL_CONSTRUCTOR]);
   }
   void test_finalMethod() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "final int m() {}", [ParserErrorCode.FINAL_METHOD]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "final int m() {}", [ParserErrorCode.FINAL_METHOD]);
   }
   void test_finalTypedef() {
-    ParserTestCase.parse4("parseCompilationUnit", "final typedef F();", [ParserErrorCode.FINAL_TYPEDEF]);
+    ParserTestCase.parse5("parseCompilationUnit", "final typedef F();", [ParserErrorCode.FINAL_TYPEDEF]);
   }
   void test_getterWithParameters() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "int get x() {}", [ParserErrorCode.GETTER_WITH_PARAMETERS]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "int get x() {}", [ParserErrorCode.GETTER_WITH_PARAMETERS]);
   }
   void test_illegalAssignmentToNonAssignable_superAssigned() {
-    ParserTestCase.parse4("parseExpression", "super = x;", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
+    ParserTestCase.parse5("parseExpression", "super = x;", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
   }
   void test_implementsBeforeExtends() {
-    ParserTestCase.parse4("parseCompilationUnit", "class A implements B extends C {}", [ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS]);
+    ParserTestCase.parse5("parseCompilationUnit", "class A implements B extends C {}", [ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS]);
   }
   void test_implementsBeforeWith() {
-    ParserTestCase.parse4("parseCompilationUnit", "class A extends B implements C with D {}", [ParserErrorCode.IMPLEMENTS_BEFORE_WITH]);
+    ParserTestCase.parse5("parseCompilationUnit", "class A extends B implements C with D {}", [ParserErrorCode.IMPLEMENTS_BEFORE_WITH]);
   }
   void test_importDirectiveAfterPartDirective() {
-    ParserTestCase.parse4("parseCompilationUnit", "part 'a.dart'; import 'b.dart';", [ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE]);
+    ParserTestCase.parse5("parseCompilationUnit", "part 'a.dart'; import 'b.dart';", [ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE]);
   }
   void test_initializedVariableInForEach() {
-    ParserTestCase.parse4("parseForStatement", "for (int a = 0 in foo) {}", [ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH]);
+    ParserTestCase.parse5("parseForStatement", "for (int a = 0 in foo) {}", [ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH]);
   }
   void test_invalidCodePoint() {
-    ParserTestCase.parse4("parseStringLiteral", "'\\uD900'", [ParserErrorCode.INVALID_CODE_POINT]);
+    ParserTestCase.parse5("parseStringLiteral", "'\\uD900'", [ParserErrorCode.INVALID_CODE_POINT]);
   }
   void test_invalidHexEscape_invalidDigit() {
-    ParserTestCase.parse4("parseStringLiteral", "'\\x0 a'", [ParserErrorCode.INVALID_HEX_ESCAPE]);
+    ParserTestCase.parse5("parseStringLiteral", "'\\x0 a'", [ParserErrorCode.INVALID_HEX_ESCAPE]);
   }
   void test_invalidHexEscape_tooFewDigits() {
-    ParserTestCase.parse4("parseStringLiteral", "'\\x0'", [ParserErrorCode.INVALID_HEX_ESCAPE]);
+    ParserTestCase.parse5("parseStringLiteral", "'\\x0'", [ParserErrorCode.INVALID_HEX_ESCAPE]);
   }
   void test_invalidOperatorForSuper() {
-    ParserTestCase.parse4("parseUnaryExpression", "++super", [ParserErrorCode.INVALID_OPERATOR_FOR_SUPER]);
+    ParserTestCase.parse5("parseUnaryExpression", "++super", [ParserErrorCode.INVALID_OPERATOR_FOR_SUPER]);
   }
   void test_invalidUnicodeEscape_incomplete_noDigits() {
-    ParserTestCase.parse4("parseStringLiteral", "'\\u{'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
+    ParserTestCase.parse5("parseStringLiteral", "'\\u{'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
   }
   void test_invalidUnicodeEscape_incomplete_someDigits() {
-    ParserTestCase.parse4("parseStringLiteral", "'\\u{0A'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
+    ParserTestCase.parse5("parseStringLiteral", "'\\u{0A'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
   }
   void test_invalidUnicodeEscape_invalidDigit() {
-    ParserTestCase.parse4("parseStringLiteral", "'\\u0 a'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
+    ParserTestCase.parse5("parseStringLiteral", "'\\u0 a'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
   }
   void test_invalidUnicodeEscape_tooFewDigits_fixed() {
-    ParserTestCase.parse4("parseStringLiteral", "'\\u04'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
+    ParserTestCase.parse5("parseStringLiteral", "'\\u04'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
   }
   void test_invalidUnicodeEscape_tooFewDigits_variable() {
-    ParserTestCase.parse4("parseStringLiteral", "'\\u{}'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
+    ParserTestCase.parse5("parseStringLiteral", "'\\u{}'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
   }
   void test_invalidUnicodeEscape_tooManyDigits_variable() {
-    ParserTestCase.parse4("parseStringLiteral", "'\\u{12345678}'", [ParserErrorCode.INVALID_UNICODE_ESCAPE, ParserErrorCode.INVALID_CODE_POINT]);
+    ParserTestCase.parse5("parseStringLiteral", "'\\u{12345678}'", [ParserErrorCode.INVALID_UNICODE_ESCAPE, ParserErrorCode.INVALID_CODE_POINT]);
   }
   void test_libraryDirectiveNotFirst() {
-    ParserTestCase.parse4("parseCompilationUnit", "import 'x.dart'; library l;", [ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST]);
+    ParserTestCase.parse5("parseCompilationUnit", "import 'x.dart'; library l;", [ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST]);
   }
   void test_libraryDirectiveNotFirst_afterPart() {
-    CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "part 'a.dart';\nlibrary l;", [ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST]);
+    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "part 'a.dart';\nlibrary l;", [ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST]);
     JUnitTestCase.assertNotNull(unit);
   }
   void test_missingAssignableSelector_identifiersAssigned() {
-    ParserTestCase.parse4("parseExpression", "x.y = y;", []);
+    ParserTestCase.parse5("parseExpression", "x.y = y;", []);
   }
   void test_missingAssignableSelector_primarySelectorPostfix() {
-    ParserTestCase.parse4("parseExpression", "x(y)(z)++", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]);
+    ParserTestCase.parse5("parseExpression", "x(y)(z)++", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]);
   }
   void test_missingAssignableSelector_selector() {
-    ParserTestCase.parse4("parseExpression", "x(y)(z).a++", []);
+    ParserTestCase.parse5("parseExpression", "x(y)(z).a++", []);
   }
   void test_missingAssignableSelector_superPrimaryExpression() {
-    SuperExpression expression = ParserTestCase.parse4("parsePrimaryExpression", "super", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]);
+    SuperExpression expression = ParserTestCase.parse5("parsePrimaryExpression", "super", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]);
     JUnitTestCase.assertNotNull(expression.keyword);
   }
   void test_missingAssignableSelector_superPropertyAccessAssigned() {
-    ParserTestCase.parse4("parseExpression", "super.x = x;", []);
+    ParserTestCase.parse5("parseExpression", "super.x = x;", []);
   }
   void test_missingCatchOrFinally() {
-    TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {}", [ParserErrorCode.MISSING_CATCH_OR_FINALLY]);
+    TryStatement statement = ParserTestCase.parse5("parseTryStatement", "try {}", [ParserErrorCode.MISSING_CATCH_OR_FINALLY]);
     JUnitTestCase.assertNotNull(statement);
   }
   void test_missingClassBody() {
-    ParserTestCase.parse4("parseCompilationUnit", "class A class B {}", [ParserErrorCode.MISSING_CLASS_BODY]);
+    ParserTestCase.parse5("parseCompilationUnit", "class A class B {}", [ParserErrorCode.MISSING_CLASS_BODY]);
   }
   void test_missingConstFinalVarOrType() {
-    ParserTestCase.parse3("parseFinalConstVarOrType", <Object> [false], "a;", [ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE]);
+    ParserTestCase.parse4("parseFinalConstVarOrType", <Object> [false], "a;", [ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE]);
   }
   void test_missingFunctionBody_emptyNotAllowed() {
-    ParserTestCase.parse3("parseFunctionBody", <Object> [false, false], ";", [ParserErrorCode.MISSING_FUNCTION_BODY]);
+    ParserTestCase.parse4("parseFunctionBody", <Object> [false, false], ";", [ParserErrorCode.MISSING_FUNCTION_BODY]);
   }
   void test_missingFunctionBody_invalid() {
-    ParserTestCase.parse3("parseFunctionBody", <Object> [false, false], "return 0;", [ParserErrorCode.MISSING_FUNCTION_BODY]);
+    ParserTestCase.parse4("parseFunctionBody", <Object> [false, false], "return 0;", [ParserErrorCode.MISSING_FUNCTION_BODY]);
   }
   void test_missingFunctionParameters_local_void_block() {
-    ParserTestCase.parse4("parseStatement", "void f { return x;}", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
+    ParserTestCase.parse5("parseStatement", "void f { return x;}", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
   }
   void test_missingFunctionParameters_local_void_expression() {
-    ParserTestCase.parse4("parseStatement", "void f => x;", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
+    ParserTestCase.parse5("parseStatement", "void f => x;", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
   }
   void test_missingFunctionParameters_topLevel_nonVoid_block() {
-    ParserTestCase.parse4("parseCompilationUnit", "int f { return x;}", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
+    ParserTestCase.parse5("parseCompilationUnit", "int f { return x;}", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
   }
   void test_missingFunctionParameters_topLevel_nonVoid_expression() {
-    ParserTestCase.parse4("parseCompilationUnit", "int f => x;", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
+    ParserTestCase.parse5("parseCompilationUnit", "int f => x;", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
   }
   void test_missingFunctionParameters_topLevel_void_block() {
-    ParserTestCase.parse4("parseCompilationUnit", "void f { return x;}", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
+    ParserTestCase.parse5("parseCompilationUnit", "void f { return x;}", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
   }
   void test_missingFunctionParameters_topLevel_void_expression() {
-    ParserTestCase.parse4("parseCompilationUnit", "void f => x;", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
+    ParserTestCase.parse5("parseCompilationUnit", "void f => x;", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
   }
   void test_missingIdentifier_functionDeclaration_returnTypeWithoutName() {
-    ParserTestCase.parse4("parseFunctionDeclarationStatement", "A<T> () {}", [ParserErrorCode.MISSING_IDENTIFIER]);
+    ParserTestCase.parse5("parseFunctionDeclarationStatement", "A<T> () {}", [ParserErrorCode.MISSING_IDENTIFIER]);
   }
   void test_missingIdentifier_number() {
-    SimpleIdentifier expression = ParserTestCase.parse4("parseSimpleIdentifier", "1", [ParserErrorCode.MISSING_IDENTIFIER]);
+    SimpleIdentifier expression = ParserTestCase.parse5("parseSimpleIdentifier", "1", [ParserErrorCode.MISSING_IDENTIFIER]);
     JUnitTestCase.assertTrue(expression.isSynthetic());
   }
   void test_missingNameInLibraryDirective() {
-    CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "library;", [ParserErrorCode.MISSING_NAME_IN_LIBRARY_DIRECTIVE]);
+    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "library;", [ParserErrorCode.MISSING_NAME_IN_LIBRARY_DIRECTIVE]);
     JUnitTestCase.assertNotNull(unit);
   }
   void test_missingNameInPartOfDirective() {
-    CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "part of;", [ParserErrorCode.MISSING_NAME_IN_PART_OF_DIRECTIVE]);
+    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "part of;", [ParserErrorCode.MISSING_NAME_IN_PART_OF_DIRECTIVE]);
     JUnitTestCase.assertNotNull(unit);
   }
   void test_missingTypedefParameters_nonVoid() {
-    ParserTestCase.parse4("parseCompilationUnit", "typedef int F;", [ParserErrorCode.MISSING_TYPEDEF_PARAMETERS]);
+    ParserTestCase.parse5("parseCompilationUnit", "typedef int F;", [ParserErrorCode.MISSING_TYPEDEF_PARAMETERS]);
   }
   void test_missingTypedefParameters_typeParameters() {
-    ParserTestCase.parse4("parseCompilationUnit", "typedef F<E>;", [ParserErrorCode.MISSING_TYPEDEF_PARAMETERS]);
+    ParserTestCase.parse5("parseCompilationUnit", "typedef F<E>;", [ParserErrorCode.MISSING_TYPEDEF_PARAMETERS]);
   }
   void test_missingTypedefParameters_void() {
-    ParserTestCase.parse4("parseCompilationUnit", "typedef void F;", [ParserErrorCode.MISSING_TYPEDEF_PARAMETERS]);
+    ParserTestCase.parse5("parseCompilationUnit", "typedef void F;", [ParserErrorCode.MISSING_TYPEDEF_PARAMETERS]);
   }
   void test_missingVariableInForEach() {
-    ParserTestCase.parse4("parseForStatement", "for (a < b in foo) {}", [ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH]);
+    ParserTestCase.parse5("parseForStatement", "for (a < b in foo) {}", [ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH]);
   }
   void test_mixedParameterGroups_namedPositional() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, {b}, [c])", [ParserErrorCode.MIXED_PARAMETER_GROUPS]);
+    ParserTestCase.parse5("parseFormalParameterList", "(a, {b}, [c])", [ParserErrorCode.MIXED_PARAMETER_GROUPS]);
   }
   void test_mixedParameterGroups_positionalNamed() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, [b], {c})", [ParserErrorCode.MIXED_PARAMETER_GROUPS]);
+    ParserTestCase.parse5("parseFormalParameterList", "(a, [b], {c})", [ParserErrorCode.MIXED_PARAMETER_GROUPS]);
   }
   void test_multipleLibraryDirectives() {
-    ParserTestCase.parse4("parseCompilationUnit", "library l; library m;", [ParserErrorCode.MULTIPLE_LIBRARY_DIRECTIVES]);
+    ParserTestCase.parse5("parseCompilationUnit", "library l; library m;", [ParserErrorCode.MULTIPLE_LIBRARY_DIRECTIVES]);
   }
   void test_multipleNamedParameterGroups() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, {b}, {c})", [ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS]);
+    ParserTestCase.parse5("parseFormalParameterList", "(a, {b}, {c})", [ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS]);
   }
   void test_multiplePartOfDirectives() {
-    ParserTestCase.parse4("parseCompilationUnit", "part of l; part of m;", [ParserErrorCode.MULTIPLE_PART_OF_DIRECTIVES]);
+    ParserTestCase.parse5("parseCompilationUnit", "part of l; part of m;", [ParserErrorCode.MULTIPLE_PART_OF_DIRECTIVES]);
   }
   void test_multiplePositionalParameterGroups() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, [b], [c])", [ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS]);
+    ParserTestCase.parse5("parseFormalParameterList", "(a, [b], [c])", [ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS]);
   }
   void test_multipleVariablesInForEach() {
-    ParserTestCase.parse4("parseForStatement", "for (int a, b in foo) {}", [ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH]);
+    ParserTestCase.parse5("parseForStatement", "for (int a, b in foo) {}", [ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH]);
   }
   void test_namedParameterOutsideGroup() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, b : 0)", [ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP]);
+    ParserTestCase.parse5("parseFormalParameterList", "(a, b : 0)", [ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP]);
   }
   void test_nonConstructorFactory_field() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "factory int x;", [ParserErrorCode.NON_CONSTRUCTOR_FACTORY]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "factory int x;", [ParserErrorCode.NON_CONSTRUCTOR_FACTORY]);
   }
   void test_nonConstructorFactory_method() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "factory int m() {}", [ParserErrorCode.NON_CONSTRUCTOR_FACTORY]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "factory int m() {}", [ParserErrorCode.NON_CONSTRUCTOR_FACTORY]);
   }
   void test_nonIdentifierLibraryName_library() {
-    CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "library 'lib';", [ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME]);
+    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "library 'lib';", [ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME]);
     JUnitTestCase.assertNotNull(unit);
   }
   void test_nonIdentifierLibraryName_partOf() {
-    CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "part of 'lib';", [ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME]);
+    CompilationUnit unit = ParserTestCase.parse5("parseCompilationUnit", "part of 'lib';", [ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME]);
     JUnitTestCase.assertNotNull(unit);
   }
   void test_nonPartOfDirectiveInPart_after() {
-    ParserTestCase.parse4("parseCompilationUnit", "part of l; part 'f.dart';", [ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART]);
+    ParserTestCase.parse5("parseCompilationUnit", "part of l; part 'f.dart';", [ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART]);
   }
   void test_nonPartOfDirectiveInPart_before() {
-    ParserTestCase.parse4("parseCompilationUnit", "part 'f.dart'; part of m;", [ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART]);
+    ParserTestCase.parse5("parseCompilationUnit", "part 'f.dart'; part of m;", [ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART]);
   }
   void test_nonUserDefinableOperator() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "operator +=(int x) => x + 1;", [ParserErrorCode.NON_USER_DEFINABLE_OPERATOR]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "operator +=(int x) => x + 1;", [ParserErrorCode.NON_USER_DEFINABLE_OPERATOR]);
   }
   void test_positionalAfterNamedArgument() {
-    ParserTestCase.parse4("parseArgumentList", "(x: 1, 2)", [ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT]);
+    ParserTestCase.parse5("parseArgumentList", "(x: 1, 2)", [ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT]);
   }
   void test_positionalParameterOutsideGroup() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, b = 0)", [ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP]);
+    ParserTestCase.parse5("parseFormalParameterList", "(a, b = 0)", [ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP]);
   }
   void test_staticAfterConst() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "final static int f;", [ParserErrorCode.STATIC_AFTER_FINAL]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "final static int f;", [ParserErrorCode.STATIC_AFTER_FINAL]);
   }
   void test_staticAfterFinal() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "const static int f;", [ParserErrorCode.STATIC_AFTER_CONST]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "const static int f;", [ParserErrorCode.STATIC_AFTER_CONST]);
   }
   void test_staticAfterVar() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "var static f;", [ParserErrorCode.STATIC_AFTER_VAR]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "var static f;", [ParserErrorCode.STATIC_AFTER_VAR]);
   }
   void test_staticConstructor() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "static C.m() {}", [ParserErrorCode.STATIC_CONSTRUCTOR]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "static C.m() {}", [ParserErrorCode.STATIC_CONSTRUCTOR]);
   }
   void test_staticOperator_noReturnType() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "static operator +(int x) => x + 1;", [ParserErrorCode.STATIC_OPERATOR]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "static operator +(int x) => x + 1;", [ParserErrorCode.STATIC_OPERATOR]);
   }
   void test_staticOperator_returnType() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "static int operator +(int x) => x + 1;", [ParserErrorCode.STATIC_OPERATOR]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "static int operator +(int x) => x + 1;", [ParserErrorCode.STATIC_OPERATOR]);
   }
   void test_staticTopLevelDeclaration_class() {
-    ParserTestCase.parse4("parseCompilationUnit", "static class C {}", [ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION]);
+    ParserTestCase.parse5("parseCompilationUnit", "static class C {}", [ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION]);
   }
   void test_staticTopLevelDeclaration_typedef() {
-    ParserTestCase.parse4("parseCompilationUnit", "static typedef F();", [ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION]);
+    ParserTestCase.parse5("parseCompilationUnit", "static typedef F();", [ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION]);
   }
   void test_staticTopLevelDeclaration_variable() {
-    ParserTestCase.parse4("parseCompilationUnit", "static var x;", [ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION]);
+    ParserTestCase.parse5("parseCompilationUnit", "static var x;", [ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION]);
   }
   void test_unexpectedToken_semicolonBetweenClassMembers() {
-    ParserTestCase.parse3("parseClassDeclaration", <Object> [emptyCommentAndMetadata(), null], "class C { int x; ; int y;}", [ParserErrorCode.UNEXPECTED_TOKEN]);
+    ParserTestCase.parse4("parseClassDeclaration", <Object> [emptyCommentAndMetadata(), null], "class C { int x; ; int y;}", [ParserErrorCode.UNEXPECTED_TOKEN]);
   }
   void test_unexpectedToken_semicolonBetweenCompilationUnitMembers() {
-    ParserTestCase.parse4("parseCompilationUnit", "int x; ; int y;", [ParserErrorCode.UNEXPECTED_TOKEN]);
+    ParserTestCase.parse5("parseCompilationUnit", "int x; ; int y;", [ParserErrorCode.UNEXPECTED_TOKEN]);
   }
   void test_useOfUnaryPlusOperator() {
-    ParserTestCase.parse4("parseUnaryExpression", "+x", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
+    ParserTestCase.parse5("parseUnaryExpression", "+x", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
   }
   void test_varClass() {
-    ParserTestCase.parse4("parseCompilationUnit", "var class C {}", [ParserErrorCode.VAR_CLASS]);
+    ParserTestCase.parse5("parseCompilationUnit", "var class C {}", [ParserErrorCode.VAR_CLASS]);
   }
   void test_varConstructor() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "var C() {}", [ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "var C() {}", [ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE]);
   }
   void test_varReturnType() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "var m() {}", [ParserErrorCode.VAR_RETURN_TYPE]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "var m() {}", [ParserErrorCode.VAR_RETURN_TYPE]);
   }
   void test_varTypedef() {
-    ParserTestCase.parse4("parseCompilationUnit", "var typedef F();", [ParserErrorCode.VAR_TYPEDEF]);
+    ParserTestCase.parse5("parseCompilationUnit", "var typedef F();", [ParserErrorCode.VAR_TYPEDEF]);
   }
   void test_voidField_initializer() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "void x = 0;", [ParserErrorCode.VOID_VARIABLE]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "void x = 0;", [ParserErrorCode.VOID_VARIABLE]);
   }
   void test_voidField_noInitializer() {
-    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "void x;", [ParserErrorCode.VOID_VARIABLE]);
+    ParserTestCase.parse4("parseClassMember", <Object> ["C"], "void x;", [ParserErrorCode.VOID_VARIABLE]);
   }
   void test_voidParameter() {
-    ParserTestCase.parse4("parseNormalFormalParameter", "void a)", [ParserErrorCode.VOID_PARAMETER]);
+    ParserTestCase.parse5("parseNormalFormalParameter", "void a)", [ParserErrorCode.VOID_PARAMETER]);
   }
   void test_withBeforeExtends() {
-    ParserTestCase.parse4("parseCompilationUnit", "class A with B extends C {}", [ParserErrorCode.WITH_BEFORE_EXTENDS]);
+    ParserTestCase.parse5("parseCompilationUnit", "class A with B extends C {}", [ParserErrorCode.WITH_BEFORE_EXTENDS]);
   }
   void test_withWithoutExtends() {
-    ParserTestCase.parse3("parseClassDeclaration", <Object> [emptyCommentAndMetadata(), null], "class A with B, C {}", [ParserErrorCode.WITH_WITHOUT_EXTENDS]);
+    ParserTestCase.parse4("parseClassDeclaration", <Object> [emptyCommentAndMetadata(), null], "class A with B, C {}", [ParserErrorCode.WITH_WITHOUT_EXTENDS]);
   }
   void test_wrongSeparatorForNamedParameter() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, {b = 0})", [ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER]);
+    ParserTestCase.parse5("parseFormalParameterList", "(a, {b = 0})", [ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER]);
   }
   void test_wrongSeparatorForPositionalParameter() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, [b : 0])", [ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER]);
+    ParserTestCase.parse5("parseFormalParameterList", "(a, [b : 0])", [ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER]);
   }
   static dartSuite() {
     _ut.group('ErrorParserTest', () {
diff --git a/pkg/analyzer-experimental/test/generated/scanner_test.dart b/pkg/analyzer-experimental/test/generated/scanner_test.dart
index 3fce7f6..21ce0e8 100644
--- a/pkg/analyzer-experimental/test/generated/scanner_test.dart
+++ b/pkg/analyzer-experimental/test/generated/scanner_test.dart
@@ -667,8 +667,8 @@
     Token currentToken = token;
     while (currentToken != null && currentToken.type != TokenType.EOF) {
       validateStream(builder, currentToken.precedingComments);
-      TokenType type21 = currentToken.type;
-      if (type21 == TokenType.OPEN_CURLY_BRACKET || type21 == TokenType.OPEN_PAREN || type21 == TokenType.OPEN_SQUARE_BRACKET || type21 == TokenType.STRING_INTERPOLATION_EXPRESSION) {
+      TokenType type23 = currentToken.type;
+      if (identical(type23, TokenType.OPEN_CURLY_BRACKET) || identical(type23, TokenType.OPEN_PAREN) || identical(type23, TokenType.OPEN_SQUARE_BRACKET) || identical(type23, TokenType.STRING_INTERPOLATION_EXPRESSION)) {
         if (currentToken is! BeginToken) {
           builder.add("\r\nExpected BeginToken, found ");
           builder.add(currentToken.runtimeType.toString());
@@ -799,19 +799,19 @@
     int keywordCount = keywords.length;
     List<String> textToTest = new List<String>.fixedLength(keywordCount * 3);
     for (int i = 0; i < keywordCount; i++) {
-      String syntax2 = keywords[i].syntax;
-      textToTest[i] = syntax2;
-      textToTest[i + keywordCount] = "${syntax2}x";
-      textToTest[i + keywordCount * 2] = syntax2.substring(0, syntax2.length - 1);
+      String syntax3 = keywords[i].syntax;
+      textToTest[i] = syntax3;
+      textToTest[i + keywordCount] = "${syntax3}x";
+      textToTest[i + keywordCount * 2] = syntax3.substring(0, syntax3.length - 1);
     }
     KeywordState firstState = KeywordState.KEYWORD_STATE;
     for (int i = 0; i < textToTest.length; i++) {
       String text = textToTest[i];
       int index = 0;
-      int length9 = text.length;
+      int length10 = text.length;
       KeywordState state = firstState;
-      while (index < length9 && state != null) {
-        state = state.next(text.charCodeAt(index));
+      while (index < length10 && state != null) {
+        state = state.next(text.codeUnitAt(index));
         index++;
       }
       if (i < keywordCount) {
@@ -1867,9 +1867,9 @@
     Token previous3 = token.previous;
     JUnitTestCase.assertEquals(token, previous3.next);
     JUnitTestCase.assertEquals(previous3, previous3.previous);
-    Token next6 = token.next;
-    JUnitTestCase.assertEquals(next6, next6.next);
-    JUnitTestCase.assertEquals(token, next6.previous);
+    Token next7 = token.next;
+    JUnitTestCase.assertEquals(next7, next7.next);
+    JUnitTestCase.assertEquals(token, next7.previous);
   }
   void test_string_multi_double() {
     assertToken(TokenType.STRING, "\"\"\"multi-line\nstring\"\"\"");
@@ -1968,7 +1968,7 @@
   void assertError(ScannerErrorCode expectedError, int expectedOffset, String source) {
     GatheringErrorListener listener = new GatheringErrorListener();
     scan(source, listener);
-    listener.assertErrors([new AnalysisError.con2(null, expectedOffset, 1, expectedError, [source.charCodeAt(expectedOffset) as int])]);
+    listener.assertErrors([new AnalysisError.con2(null, expectedOffset, 1, expectedError, [(source.codeUnitAt(expectedOffset) as int)])]);
   }
   /**
    * Assert that when scanned the given source contains a single keyword token with the same lexeme
@@ -1984,7 +1984,7 @@
     JUnitTestCase.assertEquals(source, token.lexeme);
     Object value3 = token.value();
     JUnitTestCase.assertTrue(value3 is Keyword);
-    JUnitTestCase.assertEquals(source, (value3 as Keyword).syntax);
+    JUnitTestCase.assertEquals(source, ((value3 as Keyword)).syntax);
     token = scan2(" ${source} ");
     JUnitTestCase.assertNotNull(token);
     JUnitTestCase.assertEquals(TokenType.KEYWORD, token.type);
@@ -1993,7 +1993,7 @@
     JUnitTestCase.assertEquals(source, token.lexeme);
     value3 = token.value();
     JUnitTestCase.assertTrue(value3 is Keyword);
-    JUnitTestCase.assertEquals(source, (value3 as Keyword).syntax);
+    JUnitTestCase.assertEquals(source, ((value3 as Keyword)).syntax);
     JUnitTestCase.assertEquals(TokenType.EOF, token.next.type);
   }
   /**
@@ -2008,9 +2008,9 @@
     JUnitTestCase.assertEquals(0, originalToken.offset);
     JUnitTestCase.assertEquals(source.length, originalToken.length);
     JUnitTestCase.assertEquals(source, originalToken.lexeme);
-    if (expectedType == TokenType.SCRIPT_TAG) {
+    if (identical(expectedType, TokenType.SCRIPT_TAG)) {
       return originalToken;
-    } else if (expectedType == TokenType.SINGLE_LINE_COMMENT) {
+    } else if (identical(expectedType, TokenType.SINGLE_LINE_COMMENT)) {
       Token tokenWithSpaces = scan2(" ${source}");
       JUnitTestCase.assertNotNull(tokenWithSpaces);
       JUnitTestCase.assertEquals(expectedType, tokenWithSpaces.type);
diff --git a/pkg/analyzer-experimental/test/generated/test_support.dart b/pkg/analyzer-experimental/test/generated/test_support.dart
index 1037c15..a559098 100644
--- a/pkg/analyzer-experimental/test/generated/test_support.dart
+++ b/pkg/analyzer-experimental/test/generated/test_support.dart
@@ -42,19 +42,19 @@
    * Initialize a newly created error listener to collect errors.
    */
   GatheringErrorListener() : super() {
-    _jtd_constructor_234_impl();
+    _jtd_constructor_258_impl();
   }
-  _jtd_constructor_234_impl() {
+  _jtd_constructor_258_impl() {
   }
   /**
    * Initialize a newly created error listener to collect errors.
    */
-  GatheringErrorListener.con1(String rawSource) {
-    _jtd_constructor_235_impl(rawSource);
+  GatheringErrorListener.con1(String rawSource2) {
+    _jtd_constructor_259_impl(rawSource2);
   }
-  _jtd_constructor_235_impl(String rawSource) {
-    this._rawSource = rawSource;
-    this._markedSource = rawSource;
+  _jtd_constructor_259_impl(String rawSource2) {
+    this._rawSource = rawSource2;
+    this._markedSource = rawSource2;
   }
   /**
    * Assert that the number of errors that have been gathered matches the number of errors that are
@@ -170,7 +170,7 @@
     int expectedErrorCount = 0;
     int expectedWarningCount = 0;
     for (ErrorSeverity severity in expectedSeverities) {
-      if (severity == ErrorSeverity.ERROR) {
+      if (identical(severity, ErrorSeverity.ERROR)) {
         expectedErrorCount++;
       } else {
         expectedWarningCount++;
@@ -179,7 +179,7 @@
     int actualErrorCount = 0;
     int actualWarningCount = 0;
     for (AnalysisError error in _errors) {
-      if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) {
+      if (identical(error.errorCode.errorSeverity, ErrorSeverity.ERROR)) {
         actualErrorCount++;
       } else {
         actualWarningCount++;
@@ -194,7 +194,7 @@
    * @throws AssertionFailedError if any errors have been gathered
    */
   void assertNoErrors() {
-    assertErrors(GatheringErrorListener._NO_ERRORS);
+    assertErrors(_NO_ERRORS);
   }
   /**
    * Return the errors that were collected.
@@ -206,9 +206,9 @@
    * @param errorCode the error code being searched for
    * @return {@code true} if an error with the given error code has been gathered
    */
-  bool hasError(ErrorCode errorCode) {
+  bool hasError(ErrorCode errorCode4) {
     for (AnalysisError error in _errors) {
-      if (error.errorCode == errorCode) {
+      if (identical(error.errorCode, errorCode4)) {
         return true;
       }
     }
@@ -244,7 +244,7 @@
    * @param secondError the second error being compared
    * @return {@code true} if the two errors are equivalent
    */
-  bool equals(AnalysisError firstError, AnalysisError secondError) => firstError.errorCode == secondError.errorCode && firstError.offset == secondError.offset && firstError.length == secondError.length && equals3(firstError.source, secondError.source);
+  bool equals(AnalysisError firstError, AnalysisError secondError) => identical(firstError.errorCode, secondError.errorCode) && firstError.offset == secondError.offset && firstError.length == secondError.length && equals3(firstError.source, secondError.source);
   /**
    * Return {@code true} if the two sources are equivalent.
    * @param firstSource the first source being compared
@@ -272,15 +272,15 @@
     writer.print(expectedErrors.length);
     writer.print(" errors:");
     for (AnalysisError error in expectedErrors) {
-      Source source5 = error.source;
-      LineInfo lineInfo = _lineInfoMap[source5];
+      Source source9 = error.source;
+      LineInfo lineInfo = _lineInfoMap[source9];
       writer.println();
       if (lineInfo == null) {
-        int offset8 = error.offset;
-        writer.printf("  %s %s (%d..%d)", [source5 == null ? "" : source5.shortName, error.errorCode, offset8, offset8 + error.length]);
+        int offset9 = error.offset;
+        writer.printf("  %s %s (%d..%d)", [source9 == null ? "" : source9.shortName, error.errorCode, offset9, offset9 + error.length]);
       } else {
         LineInfo_Location location = lineInfo.getLocation(error.offset);
-        writer.printf("  %s %s (%d, %d/%d)", [source5 == null ? "" : source5.shortName, error.errorCode, location.lineNumber, location.columnNumber, error.length]);
+        writer.printf("  %s %s (%d, %d/%d)", [source9 == null ? "" : source9.shortName, error.errorCode, location.lineNumber, location.columnNumber, error.length]);
       }
     }
     writer.println();
@@ -288,15 +288,15 @@
     writer.print(_errors.length);
     writer.print(" errors:");
     for (AnalysisError error in _errors) {
-      Source source6 = error.source;
-      LineInfo lineInfo = _lineInfoMap[source6];
+      Source source10 = error.source;
+      LineInfo lineInfo = _lineInfoMap[source10];
       writer.println();
       if (lineInfo == null) {
-        int offset9 = error.offset;
-        writer.printf("  %s %s (%d..%d): %s", [source6 == null ? "" : source6.shortName, error.errorCode, offset9, offset9 + error.length, error.message]);
+        int offset10 = error.offset;
+        writer.printf("  %s %s (%d..%d): %s", [source10 == null ? "" : source10.shortName, error.errorCode, offset10, offset10 + error.length, error.message]);
       } else {
         LineInfo_Location location = lineInfo.getLocation(error.offset);
-        writer.printf("  %s %s (%d, %d/%d): %s", [source6 == null ? "" : source6.shortName, error.errorCode, location.lineNumber, location.columnNumber, error.length, error.message]);
+        writer.printf("  %s %s (%d, %d/%d): %s", [source10 == null ? "" : source10.shortName, error.errorCode, location.lineNumber, location.columnNumber, error.length, error.message]);
       }
     }
     JUnitTestCase.fail(writer.toString());
@@ -376,7 +376,7 @@
    */
   static void assertEqualString(String expected, String actual) {
     if (actual == null || expected == null) {
-      if (actual == expected) {
+      if (identical(actual, expected)) {
         return;
       }
       if (actual == null) {
@@ -387,8 +387,8 @@
     }
     int diffPos = getDiffPos(expected, actual);
     if (diffPos != -1) {
-      int diffAhead = Math.max(0, diffPos - EngineTestCase._PRINT_RANGE);
-      int diffAfter = Math.min(actual.length, diffPos + EngineTestCase._PRINT_RANGE);
+      int diffAhead = Math.max(0, diffPos - _PRINT_RANGE);
+      int diffAfter = Math.min(actual.length, diffPos + _PRINT_RANGE);
       String diffStr = "${actual.substring(diffAhead, diffPos)}^${actual.substring(diffPos, diffAfter)}";
       String message = "Content not as expected: is\n${actual}\nDiffers at pos ${diffPos}: ${diffStr}\nexpected:\n${expected}";
       JUnitTestCase.assertEqualsMsg(message, expected, actual);
@@ -471,7 +471,7 @@
     if (!isInstanceOf(object, expectedClass)) {
       JUnitTestCase.fail("Expected instance of ${expectedClass.toString()}, found ${(object == null ? "null" : object.runtimeType.toString())}");
     }
-    return object as Object;
+    return (object as Object);
   }
   /**
    * Assert that the given array is non-{@code null} and has the expected number of elements.
@@ -498,10 +498,10 @@
     JUnitTestCase.assertEquals(expectedToken.type, actualToken.type);
     if (expectedToken is KeywordToken) {
       assertInstanceOf(KeywordToken, actualToken);
-      JUnitTestCase.assertEquals((expectedToken as KeywordToken).keyword, (actualToken as KeywordToken).keyword);
+      JUnitTestCase.assertEquals(((expectedToken as KeywordToken)).keyword, ((actualToken as KeywordToken)).keyword);
     } else if (expectedToken is StringToken) {
       assertInstanceOf(StringToken, actualToken);
-      JUnitTestCase.assertEquals((expectedToken as StringToken).lexeme, (actualToken as StringToken).lexeme);
+      JUnitTestCase.assertEquals(((expectedToken as StringToken)).lexeme, ((actualToken as StringToken)).lexeme);
     }
   }
   /**
@@ -554,7 +554,7 @@
     int len1 = Math.min(str1.length, str2.length);
     int diffPos = -1;
     for (int i = 0; i < len1; i++) {
-      if (str1.charCodeAt(i) != str2.charCodeAt(i)) {
+      if (str1.codeUnitAt(i) != str2.codeUnitAt(i)) {
         diffPos = i;
         break;
       }
diff --git a/pkg/args/pubspec.yaml b/pkg/args/pubspec.yaml
index b4b1e45..959c189 100644
--- a/pkg/args/pubspec.yaml
+++ b/pkg/args/pubspec.yaml
@@ -1,7 +1,7 @@
 name: args
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
-documentation: http://api.dartlang.org/docs/pkg/args.html
+documentation: http://api.dartlang.org/docs/pkg/args
 description: >
  Libraries for defining parsers for parsing raw command-line arguments into
  a set of options and values using GNU and POSIX style options.
diff --git a/pkg/browser/README.md b/pkg/browser/README.md
new file mode 100644
index 0000000..32c736c
--- /dev/null
+++ b/pkg/browser/README.md
@@ -0,0 +1,22 @@
+The dart.js file is used in Dart browser apps to check for native Dart support
+and either (a) bootstrap Dartium or (b) load compiled JS instead.  Previously,
+we've recommended that you add a script tag pointing the version of dart.js in
+our repository.  This doesn't work offline and also results in slower startup
+(see [dartbug.com/6723](http://dartbug.com/6723)).
+
+Instead, we now recommend that you install dart.js via the following steps:
+
+1. Add the following to your pubspec.yaml:
+  dependencies:
+    browser: any
+
+2. Run pub install.
+
+3. Use a relative script tag in your html to the installed version:
+
+    `<script src="packages/browser/dart.js"></script>`
+
+If you do not wish to use pub, you may host a copy of this file locally instead.
+In this case, you will need to update it yourself as necessary.  We reserve the
+right to move the old file in the repository, so we no longer recommend linking
+to it directly.
diff --git a/pkg/browser/lib/dart.js b/pkg/browser/lib/dart.js
index bf60f52..ee339de7 100644
--- a/pkg/browser/lib/dart.js
+++ b/pkg/browser/lib/dart.js
@@ -25,7 +25,7 @@
         // Remap foo.dart to foo.dart.js.
         if (scripts[i].src && scripts[i].src != '') {
           var script = document.createElement('script');
-          script.src = scripts[i].src + '.js';
+          script.src = scripts[i].src.replace(/\.dart(?=\?|$)/, '.dart.js');
           var parent = scripts[i].parentNode;
           parent.replaceChild(script, scripts[i]);
         }
diff --git a/pkg/intl/pubspec.yaml b/pkg/intl/pubspec.yaml
index 4127fa0..0a870a0 100644
--- a/pkg/intl/pubspec.yaml
+++ b/pkg/intl/pubspec.yaml
@@ -1,7 +1,7 @@
 name: intl
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
-documentation: http://api.dartlang.org/docs/pkg/intl.html
+documentation: http://api.dartlang.org/docs/pkg/intl
 description: >
   Contains code to deal with internationalized/localized
   messages, date and number formatting and parsing,
diff --git a/pkg/logging/pubspec.yaml b/pkg/logging/pubspec.yaml
index 5c2c045..208667b 100644
--- a/pkg/logging/pubspec.yaml
+++ b/pkg/logging/pubspec.yaml
@@ -1,7 +1,7 @@
 name: logging
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
-documentation: http://api.dartlang.org/docs/pkg/logging.html
+documentation: http://api.dartlang.org/docs/pkg/logging
 description: >
  Provides APIs for debugging and error logging. This library introduces
  abstractions similar to those used in other languages, such as the Closure JS
diff --git a/pkg/meta/pubspec.yaml b/pkg/meta/pubspec.yaml
index 894c695..1a06bbc 100644
--- a/pkg/meta/pubspec.yaml
+++ b/pkg/meta/pubspec.yaml
@@ -1,7 +1,7 @@
 name: meta
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
-documentation: http://api.dartlang.org/docs/pkg/meta.html
+documentation: http://api.dartlang.org/docs/pkg/meta
 description: >
  This library contains the definitions of annotations that provide additional
  semantic information about the program being annotated. These annotations are
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 69fbaee..9933564 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -36,6 +36,8 @@
 analyzer-experimental/test/options_test: Skip # Imports dart:io.
 analyzer-experimental/test/generated/parser_test: Skip # Imports dart:io.
 analyzer-experimental/test/generated/scanner_test: Skip # Imports dart:io.
+analyzer-experimental/test/generated/element_test: Skip # Imports dart:io.
+analyzer-experimental/test/generated/ast_test: Skip # Imports dart:io.
 
 # Issue 8440 forces us to use path in the scheduled_test tests, which would
 # otherwise be dart2js-compatible.
@@ -66,6 +68,8 @@
 serialization/test/serialization_test: Skip
 analyzer-experimental/test/generated/parser_test: Skip
 analyzer-experimental/test/generated/scanner_test: Skip
+analyzer-experimental/test/generated/element_test: Skip
+analyzer-experimental/test/generated/ast_test: Skip
 
 [ $compiler == dartc ]
 unittest/test/mock_regexp_negative_test: Fail
diff --git a/pkg/serialization/pubspec.yaml b/pkg/serialization/pubspec.yaml
index 897348c..c3ab332 100644
--- a/pkg/serialization/pubspec.yaml
+++ b/pkg/serialization/pubspec.yaml
@@ -1,7 +1,7 @@
 name: serialization
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
-documentation: http://api.dartlang.org/docs/pkg/serialization.html
+documentation: http://api.dartlang.org/docs/pkg/serialization
 description: >
   Provide a serialization facility for Dart objects.
 dependencies:
diff --git a/pkg/unittest/pubspec.yaml b/pkg/unittest/pubspec.yaml
index 9a2a484..07be11a 100644
--- a/pkg/unittest/pubspec.yaml
+++ b/pkg/unittest/pubspec.yaml
@@ -1,7 +1,7 @@
 name: unittest
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
-documentation: http://api.dartlang.org/docs/pkg/unittest.html
+documentation: http://api.dartlang.org/docs/pkg/unittest
 description: >
  A library for writing dart unit tests.
 dependencies:
diff --git a/sdk/lib/_internal/compiler/implementation/lib/foreign_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/foreign_helper.dart
index 177295b..97700a7 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/foreign_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/foreign_helper.dart
@@ -133,6 +133,15 @@
 dynamic JS_CREATE_ISOLATE() {}
 
 /**
+ * Returns the JavaScript constructor function for Dart's Object class.
+ * This can be used for type tests, as in
+ *
+ *     if (JS('bool', '# instanceof #', obj, JS_DART_OBJECT_CONSTRUCTOR()))
+ *       ...
+ */
+dynamic JS_DART_OBJECT_CONSTRUCTOR() {}
+
+/**
  * Returns the prefix used for generated is checks on classes.
  */
 String JS_OPERATOR_IS_PREFIX() {}
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
index 61f532e..844ee78 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
@@ -9,6 +9,7 @@
                                    JS,
                                    JS_CALL_IN_ISOLATE,
                                    JS_CURRENT_ISOLATE,
+                                   JS_DART_OBJECT_CONSTRUCTOR,
                                    JS_OPERATOR_IS_PREFIX,
                                    JS_OPERATOR_AS_PREFIX,
                                    JS_HAS_EQUALS,
diff --git a/sdk/lib/_internal/compiler/implementation/lib/native_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/native_helper.dart
index c75e554..db9229a 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/native_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/native_helper.dart
@@ -240,14 +240,18 @@
   // The tag is related to the class name.  E.g. the dart:html class
   // '_ButtonElement' has the tag 'HTMLButtonElement'.  TODO(erikcorry): rename
   // getTypeNameOf to getTypeTag.
-  String tag = getTypeNameOf(obj);
-  var hasOwnPropertyFunction = JS('var', 'Object.prototype.hasOwnProperty');
 
-  var method = dynamicBindLookup(hasOwnPropertyFunction, tag, methods);
-  if (method == null) {
-    String secondTag = alternateTag(obj, tag);
-    if (secondTag != null) {
-      method = dynamicBindLookup(hasOwnPropertyFunction, secondTag, methods);
+  var hasOwnPropertyFunction = JS('var', 'Object.prototype.hasOwnProperty');
+  var method = null;
+  if (!isDartObject(obj)) {
+    String tag = getTypeNameOf(obj);
+
+    method = dynamicBindLookup(hasOwnPropertyFunction, tag, methods);
+    if (method == null) {
+      String secondTag = alternateTag(obj, tag);
+      if (secondTag != null) {
+        method = dynamicBindLookup(hasOwnPropertyFunction, secondTag, methods);
+      }
     }
   }
 
@@ -255,34 +259,33 @@
   // getTypeNameOf in case the minifier has renamed Object.
   if (method == null) {
     String nameOfObjectClass = getTypeNameOf(const Object());
-    method =
-        lookupDynamicClass(hasOwnPropertyFunction, methods, nameOfObjectClass);
+    method = lookupDynamicClass(
+        hasOwnPropertyFunction, methods, nameOfObjectClass);
   }
 
-  var proto = JS('var', 'Object.getPrototypeOf(#)', obj);
   if (method == null) {
-    // If the method cannot be found, we use a trampoline method that
-    // will throw a [NoSuchMethodError] if the object is of the
-    // exact prototype, or will call [dynamicBind] again if the object
-    // is a subclass.
-    method = JS('var',
-        'function () {'
-          'if (Object.getPrototypeOf(this) === #) {'
-            'throw new TypeError(# + " is not a function");'
-          '} else {'
-            'return Object.prototype[#].apply(this, arguments);'
-          '}'
-        '}',
-      proto, name, name);
-  }
-
-  if (!callHasOwnProperty(hasOwnPropertyFunction, proto, name)) {
-    defineProperty(proto, name, method);
+    // Throw the `TypeError` that would have happened if this dynamic bind hook
+    // had not been installed on `Object.prototype`.
+    JS('void',
+       // `(function(){...})()` converts statement `throw` into an expression.
+       '(function(){throw new TypeError(# + " is not a function");})()',
+       name);
+  } else {
+    var proto = JS('var', 'Object.getPrototypeOf(#)', obj);
+    if (!callHasOwnProperty(hasOwnPropertyFunction, proto, name)) {
+      defineProperty(proto, name, method);
+    }
   }
 
   return JS('var', '#.apply(#, #)', method, obj, arguments);
 }
 
+// Is [obj] an instance of a Dart-defined class?
+bool isDartObject(obj) {
+  // Some of the extra parens here are necessary.
+  return JS('bool', '((#) instanceof (#))', obj, JS_DART_OBJECT_CONSTRUCTOR());
+}
+
 dynamicBindLookup(var hasOwnPropertyFunction, String tag, var methods) {
   var method = lookupDynamicClass(hasOwnPropertyFunction, methods, tag);
   // Look at the inheritance data, getting the class tags and using them
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 916b4db..264334a 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -3010,6 +3010,16 @@
                       <HInstruction>[]));
   }
 
+  void handleForeignDartObjectJsConstructorFunction(Send node) {
+    if (!node.arguments.isEmpty) {
+      compiler.cancel('Too many arguments', node: node.argumentsNode);
+    }
+    String jsClassReference = backend.namer.isolateAccess(compiler.objectClass);
+    push(new HForeign(new DartString.literal(jsClassReference),
+                      HType.UNKNOWN,
+                      <HInstruction>[]));
+  }
+
   visitForeignSend(Send node) {
     Selector selector = elements.getSelector(node);
     SourceString name = selector.name;
@@ -3031,6 +3041,8 @@
       stack.add(addConstantString(node, backend.namer.operatorIsPrefix()));
     } else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) {
       stack.add(addConstantString(node, backend.namer.operatorAsPrefix()));
+    } else if (name == const SourceString('JS_DART_OBJECT_CONSTRUCTOR')) {
+      handleForeignDartObjectJsConstructorFunction(node);
     } else {
       throw "Unknown foreign: ${selector}";
     }
diff --git a/sdk/lib/core/date_time.dart b/sdk/lib/core/date_time.dart
index cbeeccd..b57b630 100644
--- a/sdk/lib/core/date_time.dart
+++ b/sdk/lib/core/date_time.dart
@@ -272,45 +272,84 @@
   }
 
   /**
-   * Returns true if [this] occurs at the same time as [other]. The
-   * comparison is independent of whether the time is utc or in the local
-   * time zone.
+   * Returns true if [other] is a [DateTime] at the same moment and in the
+   * same timezone (UTC or local).
+   *
+   * See [isAtSameMomentAs] for a comparison that ignores the timezone.
    */
   bool operator ==(other) {
     if (!(other is DateTime)) return false;
-    return (millisecondsSinceEpoch == other.millisecondsSinceEpoch);
+    return (millisecondsSinceEpoch == other.millisecondsSinceEpoch &&
+            isUtc == other.isUtc);
   }
 
   /**
    * Returns true if [this] occurs before [other]. The comparison is independent
-   * of whether the time is utc or in the local time zone.
+   * of whether the time is in UTC or in the local time zone.
+   *
+   * *Deprecated* Use [isBefore] instead.
    */
+  @deprecated
   bool operator <(DateTime other)
       => millisecondsSinceEpoch < other.millisecondsSinceEpoch;
 
   /**
    * Returns true if [this] occurs at the same time or before [other]. The
-   * comparison is independent of whether the time is utc or in the local
+   * comparison is independent of whether the time is in UTC or in the local
    * time zone.
+   *
+   * *Deprecated* Use [isAfter] instead ([:!isAfter:]).
    */
+  @deprecated
   bool operator <=(DateTime other)
       => millisecondsSinceEpoch <= other.millisecondsSinceEpoch;
 
   /**
    * Returns true if [this] occurs after [other]. The comparison is independent
-   * of whether the time is utc or in the local time zone.
+   * of whether the time is in UTC or in the local time zone.
+   *
+   * *Deprecated* Use [isAfter] instead.
    */
+  @deprecated
   bool operator >(DateTime other)
       => millisecondsSinceEpoch > other.millisecondsSinceEpoch;
 
   /**
    * Returns true if [this] occurs at the same time or after [other]. The
-   * comparison is independent of whether the time is utc or in the local
+   * comparison is independent of whether the time is in UTC or in the local
    * time zone.
+   *
+   * *Deprecated* Use [isBefore] instead ([:!isBefore:]).
    */
+  @deprecated
   bool operator >=(DateTime other)
       => millisecondsSinceEpoch >= other.millisecondsSinceEpoch;
 
+  /**
+   * Returns true if [this] occurs before [other]. The comparison is independent
+   * of whether the time is in UTC or in the local time zone.
+   */
+  bool isBefore(DateTime other) {
+    return millisecondsSinceEpoch < other.millisecondsSinceEpoch;
+  }
+
+  /**
+   * Returns true if [this] occurs after [other]. The comparison is independent
+   * of whether the time is in UTC or in the local time zone.
+   */
+  bool isAfter(DateTime other) {
+    return millisecondsSinceEpoch > other.millisecondsSinceEpoch;
+  }
+
+  /**
+   * Returns true if [this] occurs at the same moment as [other]. The
+   * comparison is independent of whether the time is in UTC or in the local
+   * time zone.
+   */
+  bool isAtSameMomentAs(DateTime other) {
+    return millisecondsSinceEpoch == other.millisecondsSinceEpoch;
+  }
+
   int compareTo(DateTime other)
       => millisecondsSinceEpoch.compareTo(other.millisecondsSinceEpoch);
 
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 71f7cce..8688fea 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -8156,6 +8156,10 @@
   Iterator<Element> get iterator => toList().iterator;
 
   void addAll(Iterable<Element> iterable) {
+    if (iterable is _ChildNodeListLazy) {
+      iterable = new List.from(iterable);
+    }
+
     for (Element element in iterable) {
       _element.$dom_appendChild(element);
     }
@@ -8686,20 +8690,20 @@
    *
    * Would be accessed in Dart as:
    *
-   *     var value = element.dataAttributes['myRandomValue'];
+   *     var value = element.dataset['myRandomValue'];
    *
    * See also:
    *
    * * [Custom data attributes](http://www.w3.org/TR/html5/global-attributes.html#custom-data-attribute)
    */
-  Map<String, String> get dataAttributes =>
+  Map<String, String> get dataset =>
     new _DataAttributeMap(attributes);
 
-  void set dataAttributes(Map<String, String> value) {
-    final dataAttributes = this.dataAttributes;
-    dataAttributes.clear();
+  void set dataset(Map<String, String> value) {
+    final data = this.dataset;
+    data.clear();
     for (String key in value.keys) {
-      dataAttributes[key] = value[key];
+      data[key] = value[key];
     }
   }
 
@@ -9261,10 +9265,6 @@
   @DocsEditable
   final int clientWidth;
 
-  @DomName('Element.dataset')
-  @DocsEditable
-  final Map<String, String> dataset;
-
   @JSName('firstElementChild')
   @DomName('Element.firstElementChild')
   @DocsEditable
@@ -11607,6 +11607,10 @@
 
 @DocsEditable
 @DomName('FormData')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FormData native "*FormData" {
 
   @DomName('DOMFormData.DOMFormData')
@@ -11620,6 +11624,9 @@
   static FormData _create_1(form) => JS('FormData', 'new FormData(#)', form);
   static FormData _create_2() => JS('FormData', 'new FormData()');
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!(window.FormData)');
+
   @DomName('DOMFormData.append')
   @DocsEditable
   void append(String name, value, [String filename]) native;
@@ -12635,6 +12642,22 @@
     return completer.future;
   }
 
+  /**
+   * Checks to see if the Progress event is supported on the current platform.
+   */
+  static bool get supportsProgressEvent {
+    var xhr = new HttpRequest();
+    return JS('bool', '"onprogress" in #', xhr);
+  }
+
+  /**
+   * Checks to see if the LoadEnd event is supported on the current platform.
+   */
+  static bool get supportsLoadEndEvent {
+    var xhr = new HttpRequest();
+    return JS('bool', '"onloadend" in #', xhr);
+  }
+
 
   @DomName('XMLHttpRequest.abortEvent')
   @DocsEditable
@@ -12740,6 +12763,10 @@
    */
   @DomName('XMLHttpRequest.response')
   @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
   @Creates('ArrayBuffer|Blob|Document|=Object|=List|String|num')
   final Object response;
 
@@ -12929,6 +12956,10 @@
    */
   @DomName('XMLHttpRequest.onloadend')
   @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
   Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);
 
   /**
@@ -12948,6 +12979,10 @@
    */
   @DomName('XMLHttpRequest.onprogress')
   @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
   Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);
 
   /**
@@ -17032,6 +17067,9 @@
 
 
   void addAll(Iterable<Node> iterable) {
+    if (iterable is _ChildNodeListLazy) {
+      iterable = new List.from(iterable);
+    }
     for (Node node in iterable) {
       _this.$dom_appendChild(node);
     }
@@ -25788,6 +25826,56 @@
 @DomName('Window')
 class Window extends EventTarget implements WindowBase native "@*DOMWindow" {
 
+  /**
+   * Executes a [callback] after the immediate execution stack has completed.
+   *
+   * This differs from using Timer.run(callback)
+   * because Timer will run in about 4-15 milliseconds, depending on browser,
+   * depending on load. [setImmediate], in contrast, makes browser-specific
+   * changes in behavior to attempt to run immediately after the current
+   * frame unwinds, causing the future to complete after all processing has
+   * completed for the current event, but before any subsequent events.
+   */
+  void setImmediate(TimeoutHandler callback) { 
+    _addMicrotaskCallback(callback);
+  }
+  /**
+   * Lookup a port by its [name].  Return null if no port is
+   * registered under [name].
+   */
+  SendPortSync lookupPort(String name) {
+    var port =
+        json.parse(document.documentElement.attributes['dart-port:$name']);
+    return _deserialize(port);
+  }
+
+  /**
+   * Register a [port] on this window under the given [name].  This
+   * port may be retrieved by any isolate (or JavaScript script)
+   * running in this window.
+   */
+  void registerPort(String name, var port) {
+    var serialized = _serialize(port);
+    document.documentElement.attributes['dart-port:$name'] =
+        json.stringify(serialized);
+  }
+
+  /**
+   * Returns a Future that completes just before the window is about to repaint
+   * so the user can draw an animation frame
+   *
+   * If you need to later cancel this animation, use [requestAnimationFrame]
+   * instead.
+   *
+   * Note: The code that runs when the future completes should call 
+   * [animationFrame] again for the animation to continue.
+   */
+  Future<num> get animationFrame {
+    var completer = new Completer<int>();
+    requestAnimationFrame(completer.complete);
+    return completer.future;
+  }
+
   Document get document => JS('Document', '#.document', this);
 
   WindowBase _open2(url, name) => JS('Window', '#.open(#,#)', this, url, name);
@@ -25853,15 +25941,21 @@
   }
 
   /**
-   * Executes a [callback] after the immediate execution stack has completed.
+   * Called to draw an animation frame and then request the window to repaint
+   * after [callback] has finished (creating the animation). 
    *
-   * This will cause the callback to be executed after all processing has
-   * completed for the current event, but before any subsequent events.
+   * Use this method only if you need to later call [cancelAnimationFrame]. If
+   * not, the preferred Dart idiom is to set animation frames by calling
+   * [animationFrame], which returns a Future.
+   *
+   * Returns a non-zero valued integer to represent the request id for this
+   * request. This value only needs to be saved if you intend to call
+   * [cancelAnimationFrame] so you can specify the particular animation to
+   * cancel.
+   *
+   * Note: The supplied [callback] needs to call [requestAnimationFrame] again
+   * for the animation to continue.
    */
-  void setImmediate(TimeoutHandler callback) {
-    _addMicrotaskCallback(callback);
-  }
-
   @DomName('DOMWindow.requestAnimationFrame')
   int requestAnimationFrame(RequestAnimationFrameCallback callback) {
     _ensureRequestAnimationFrame();
@@ -25920,25 +26014,6 @@
          '#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB',
          this, this, this);
 
-  /**
-   * Lookup a port by its [name].  Return null if no port is
-   * registered under [name].
-   */
-  SendPortSync lookupPort(String name) {
-    var port = json.parse(document.documentElement.attributes['dart-port:$name']);
-    return _deserialize(port);
-  }
-
-  /**
-   * Register a [port] on this window under the given [name].  This
-   * port may be retrieved by any isolate (or JavaScript script)
-   * running in this window.
-   */
-  void registerPort(String name, var port) {
-    var serialized = _serialize(port);
-    document.documentElement.attributes['dart-port:$name'] = json.stringify(serialized);
-  }
-
   @DomName('Window.console')
   Console get console => Console.safeConsole;
 
@@ -26257,13 +26332,15 @@
   @DocsEditable
   void captureEvents() native;
 
+  @JSName('clearInterval')
   @DomName('DOMWindow.clearInterval')
   @DocsEditable
-  void clearInterval(int handle) native;
+  void _clearInterval(int handle) native;
 
+  @JSName('clearTimeout')
   @DomName('DOMWindow.clearTimeout')
   @DocsEditable
-  void clearTimeout(int handle) native;
+  void _clearTimeout(int handle) native;
 
   @DomName('DOMWindow.close')
   @DocsEditable
@@ -26375,13 +26452,15 @@
   @DocsEditable
   void scrollTo(int x, int y) native;
 
+  @JSName('setInterval')
   @DomName('DOMWindow.setInterval')
   @DocsEditable
-  int setInterval(TimeoutHandler handler, int timeout) native;
+  int _setInterval(TimeoutHandler handler, int timeout) native;
 
+  @JSName('setTimeout')
   @DomName('DOMWindow.setTimeout')
   @DocsEditable
-  int setTimeout(TimeoutHandler handler, int timeout) native;
+  int _setTimeout(TimeoutHandler handler, int timeout) native;
 
   @DomName('DOMWindow.showModalDialog')
   @DocsEditable
@@ -30009,6 +30088,7 @@
 
   // DOM events are inherently multi-subscribers.
   Stream<T> asBroadcastStream() => this;
+  bool get isBroadcast => true;
 
   StreamSubscription<T> listen(void onData(T event),
       { void onError(AsyncError error),
@@ -31377,11 +31457,11 @@
   var maker;
   var canceller;
   if (repeating) {
-    maker = window.setInterval;
-    canceller = window.clearInterval;
+    maker = window._setInterval;
+    canceller = window._clearInterval;
   } else {
-    maker = window.setTimeout;
-    canceller = window.clearTimeout;
+    maker = window._setTimeout;
+    canceller = window._clearTimeout;
   }
   Timer timer;
   final int id = maker(() { callback(timer); }, milliSeconds);
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index dfe5485..ff46655 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -8917,6 +8917,10 @@
   Iterator<Element> get iterator => toList().iterator;
 
   void addAll(Iterable<Element> iterable) {
+    if (iterable is _ChildNodeListLazy) {
+      iterable = new List.from(iterable);
+    }
+
     for (Element element in iterable) {
       _element.$dom_appendChild(element);
     }
@@ -9447,20 +9451,20 @@
    *
    * Would be accessed in Dart as:
    *
-   *     var value = element.dataAttributes['myRandomValue'];
+   *     var value = element.dataset['myRandomValue'];
    *
    * See also:
    *
    * * [Custom data attributes](http://www.w3.org/TR/html5/global-attributes.html#custom-data-attribute)
    */
-  Map<String, String> get dataAttributes =>
+  Map<String, String> get dataset =>
     new _DataAttributeMap(attributes);
 
-  void set dataAttributes(Map<String, String> value) {
-    final dataAttributes = this.dataAttributes;
-    dataAttributes.clear();
+  void set dataset(Map<String, String> value) {
+    final data = this.dataset;
+    data.clear();
     for (String key in value.keys) {
-      dataAttributes[key] = value[key];
+      data[key] = value[key];
     }
   }
 
@@ -9856,10 +9860,6 @@
   @DocsEditable
   int get clientWidth native "Element_clientWidth_Getter";
 
-  @DomName('Element.dataset')
-  @DocsEditable
-  Map<String, String> get dataset native "Element_dataset_Getter";
-
   @DomName('Element.firstElementChild')
   @DocsEditable
   Element get $dom_firstElementChild native "Element_firstElementChild_Getter";
@@ -12429,6 +12429,10 @@
 
 @DocsEditable
 @DomName('FormData')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FormData extends NativeFieldWrapperClass1 {
   FormData.internal();
   factory FormData([FormElement form]) => _create(form);
@@ -12436,6 +12440,9 @@
   @DocsEditable
   static FormData _create(form) native "DOMFormData_constructorCallback";
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('DOMFormData.append')
   @DocsEditable
   void append(String name, value, [String filename]) native "DOMFormData_append_Callback";
@@ -13533,6 +13540,20 @@
     return completer.future;
   }
 
+  /**
+   * Checks to see if the Progress event is supported on the current platform.
+   */
+  static bool get supportsProgressEvent {
+    return true;
+  }
+
+  /**
+   * Checks to see if the LoadEnd event is supported on the current platform.
+   */
+  static bool get supportsLoadEndEvent {
+    return true;
+  }
+
   HttpRequest.internal() : super.internal();
 
   @DomName('XMLHttpRequest.abortEvent')
@@ -13641,6 +13662,10 @@
    */
   @DomName('XMLHttpRequest.response')
   @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
   Object get response native "XMLHttpRequest_response_Getter";
 
   /**
@@ -13850,6 +13875,10 @@
    */
   @DomName('XMLHttpRequest.onloadend')
   @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
   Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);
 
   /**
@@ -13869,6 +13898,10 @@
    */
   @DomName('XMLHttpRequest.onprogress')
   @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @SupportedBrowser(SupportedBrowser.IE, '10')
+  @SupportedBrowser(SupportedBrowser.SAFARI)
   Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);
 
   /**
@@ -18571,6 +18604,9 @@
 
 
   void addAll(Iterable<Node> iterable) {
+    if (iterable is _ChildNodeListLazy) {
+      iterable = new List.from(iterable);
+    }
     for (Node node in iterable) {
       _this.$dom_appendChild(node);
     }
@@ -28189,19 +28225,23 @@
   /**
    * Executes a [callback] after the immediate execution stack has completed.
    *
-   * This will cause the callback to be executed after all processing has
+   * This differs from using Timer.run(callback)
+   * because Timer will run in about 4-15 milliseconds, depending on browser,
+   * depending on load. [setImmediate], in contrast, makes browser-specific
+   * changes in behavior to attempt to run immediately after the current
+   * frame unwinds, causing the future to complete after all processing has
    * completed for the current event, but before any subsequent events.
    */
-  void setImmediate(TimeoutHandler callback) {
+  void setImmediate(TimeoutHandler callback) { 
     _addMicrotaskCallback(callback);
   }
-
   /**
    * Lookup a port by its [name].  Return null if no port is
    * registered under [name].
    */
-  lookupPort(String name) {
-    var port = json.parse(document.documentElement.attributes['dart-port:$name']);
+  SendPortSync lookupPort(String name) {
+    var port =
+        json.parse(document.documentElement.attributes['dart-port:$name']);
     return _deserialize(port);
   }
 
@@ -28210,9 +28250,26 @@
    * port may be retrieved by any isolate (or JavaScript script)
    * running in this window.
    */
-  registerPort(String name, var port) {
+  void registerPort(String name, var port) {
     var serialized = _serialize(port);
-    document.documentElement.attributes['dart-port:$name'] = json.stringify(serialized);
+    document.documentElement.attributes['dart-port:$name'] =
+        json.stringify(serialized);
+  }
+
+  /**
+   * Returns a Future that completes just before the window is about to repaint
+   * so the user can draw an animation frame
+   *
+   * If you need to later cancel this animation, use [requestAnimationFrame]
+   * instead.
+   *
+   * Note: The code that runs when the future completes should call 
+   * [animationFrame] again for the animation to continue.
+   */
+  Future<num> get animationFrame {
+    var completer = new Completer<int>();
+    requestAnimationFrame(completer.complete);
+    return completer.future;
   }
 
   /// Checks if _setImmediate is supported.
@@ -28553,11 +28610,11 @@
 
   @DomName('DOMWindow.clearInterval')
   @DocsEditable
-  void clearInterval(int handle) native "DOMWindow_clearInterval_Callback";
+  void _clearInterval(int handle) native "DOMWindow_clearInterval_Callback";
 
   @DomName('DOMWindow.clearTimeout')
   @DocsEditable
-  void clearTimeout(int handle) native "DOMWindow_clearTimeout_Callback";
+  void _clearTimeout(int handle) native "DOMWindow_clearTimeout_Callback";
 
   @DomName('DOMWindow.close')
   @DocsEditable
@@ -28652,11 +28709,11 @@
 
   @DomName('DOMWindow.setInterval')
   @DocsEditable
-  int setInterval(TimeoutHandler handler, int timeout) native "DOMWindow_setInterval_Callback";
+  int _setInterval(TimeoutHandler handler, int timeout) native "DOMWindow_setInterval_Callback";
 
   @DomName('DOMWindow.setTimeout')
   @DocsEditable
-  int setTimeout(TimeoutHandler handler, int timeout) native "DOMWindow_setTimeout_Callback";
+  int _setTimeout(TimeoutHandler handler, int timeout) native "DOMWindow_setTimeout_Callback";
 
   @DomName('DOMWindow.showModalDialog')
   @DocsEditable
@@ -32480,6 +32537,7 @@
 
   // DOM events are inherently multi-subscribers.
   Stream<T> asBroadcastStream() => this;
+  bool get isBroadcast => true;
 
   StreamSubscription<T> listen(void onData(T event),
       { void onError(AsyncError error),
@@ -33848,11 +33906,11 @@
   var maker;
   var canceller;
   if (repeating) {
-    maker = window.setInterval;
-    canceller = window.clearInterval;
+    maker = window._setInterval;
+    canceller = window._clearInterval;
   } else {
-    maker = window.setTimeout;
-    canceller = window.clearTimeout;
+    maker = window._setTimeout;
+    canceller = window._clearTimeout;
   }
   Timer timer;
   final int id = maker(() { callback(timer); }, milliSeconds);
diff --git a/tests/benchmark_smoke/benchmark_base.dart b/tests/benchmark_smoke/benchmark_base.dart
index e2699cd..6b724c1 100644
--- a/tests/benchmark_smoke/benchmark_base.dart
+++ b/tests/benchmark_smoke/benchmark_base.dart
@@ -94,7 +94,7 @@
 class BenchmarkSuite {
   /** The set of benchmarks that have yet to run. */
   List<Function> benchmarks;
-  
+
   /**
    * The set of scores from the benchmarks that have already run. (Used for
    * calculating the Geometric mean).
@@ -112,15 +112,15 @@
     benchmarks = [() => Smoketest.main()];
     totalBenchmarks = benchmarks.length;
   }
-  
+
   /** Run all of the benchmarks that we have in our benchmarks list. */
   runBenchmarks() {
     runBenchmarksHelper(benchmarks);
   }
- 
+
    /**
    * Run the remaining benchmarks in our list. We chain the calls providing
-   * little breaks for the main page to gain control, so we don't force the 
+   * little breaks for the main page to gain control, so we don't force the
    * entire page to hang the whole time.
    */
   runBenchmarksHelper(List<Function> remainingBenchmarks) {
@@ -128,10 +128,11 @@
     var benchmark = remainingBenchmarks.removeLast();
     benchmark();
     if (remainingBenchmarks.length > 0) {
-      /* Provide small breaks between each benchmark, so that the browser 
+      /* Provide small breaks between each benchmark, so that the browser
       doesn't get unhappy about long running scripts, and so the user
       can regain control of the UI to kill the page as needed. */
-      window.setTimeout(() => runBenchmarksHelper(remainingBenchmarks), 25);
+      new Timer(const Duration(milliseconds: 25),
+          () => runBenchmarksHelper(remainingBenchmarks));
     } else if (remainingBenchmarks.length == 0) {
       // We've run all of the benchmarks. Update the page with the score.
       BENCHMARK_VIEW.setScore(geometricMean(scores));
@@ -140,7 +141,7 @@
 
   /** Store the results of a single benchmark run. */
   updateIndividualScore(String name, num score) {
-    scores.add(score); 
+    scores.add(score);
     BENCHMARK_VIEW.incrementProgress(name, score, totalBenchmarks);
   }
 
@@ -172,9 +173,9 @@
     body.nodes.add(
         new Element.html("<p id='testResultScore'>Score: $newScore</p>"));
   }
- 
+
   /**
-   * Update the page HTML to show how much progress we've made through the 
+   * Update the page HTML to show how much progress we've made through the
    * benchmarks.
    */
   incrementProgress(String name, num score, num totalBenchmarks) {
@@ -184,8 +185,8 @@
     // the user we're making progress.
     num percentage = 100 * numCompleted ~/ totalBenchmarks;
   }
-  
-  /** 
+
+  /**
    * Rounds the score to have at least three significant digits (hopefully)
    * helping readability of the scores.
    */
diff --git a/tests/benchmark_smoke/benchmark_lib.dart b/tests/benchmark_smoke/benchmark_lib.dart
index 33233ad..4171b28 100644
--- a/tests/benchmark_smoke/benchmark_lib.dart
+++ b/tests/benchmark_smoke/benchmark_lib.dart
@@ -4,6 +4,7 @@
 
 library benchmark_lib;
 
+import 'dart:async';
 import 'dart:html';
 import 'dart:math' as Math;
 
diff --git a/tests/benchmark_smoke/benchmark_smoke_test.dart b/tests/benchmark_smoke/benchmark_smoke_test.dart
index 2c46a48..2e45827 100644
--- a/tests/benchmark_smoke/benchmark_smoke_test.dart
+++ b/tests/benchmark_smoke/benchmark_smoke_test.dart
@@ -6,6 +6,7 @@
 
 // Tests that benchmark classes used in perf testing are not broken.
 import 'benchmark_lib.dart';
+import 'dart:async';
 import 'dart:html';
 import '../../pkg/unittest/lib/unittest.dart';
 import '../../pkg/unittest/lib/html_config.dart';
@@ -13,9 +14,9 @@
 void main() {
   useHtmlConfiguration();
 
-  test('performanceTesting', () { 
-    window.setTimeout(BENCHMARK_SUITE.runBenchmarks, 0);
-    window.setTimeout(expectAsync0(testForCompletion), 0);
+  test('performanceTesting', () {
+    Timer.run(BENCHMARK_SUITE.runBenchmarks);
+    Timer.run(expectAsync0(testForCompletion));
   });
 }
 
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index 4993c00..21a8cce 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -547,6 +547,8 @@
 LibTest/core/RegExp/allMatches_A01_t01: Fail # iterator-change, co19 issue 365
 LibTest/core/Set/Set.from_A01_t02: Fail # iterator-change, co19 issue 365
 
+LibTest/core/Date/operator_equality_A01_t01: Fail # DateTime.== now looks at timezone, co19 issue 379
+
 LibTest/core/Completer/Completer_A01_t01: Fail # Future is in async library. co19 issue 367
 LibTest/core/Completer/completeException_A01_t01: Fail # Future is in async library. co19 issue 367
 LibTest/core/Completer/completeException_A02_t01: Fail # Future is in async library. co19 issue 367
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index dee337a..a54182d 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -575,6 +575,8 @@
 LibTest/core/Queue/removeLast_A02_t01: Fail # Moved collection classes from core to collection. co19 issue 371.
 LibTest/core/Set/Set.from_A01_t01: Fail # Moved collection classes from core to collection. co19 issue 371.
 
+LibTest/core/Date/operator_equality_A01_t01: Fail # DateTime.== now looks at timezone, co19 issue 379.
+
 # Issues with co19 test suite in checked mode.
 [ $compiler == dart2js && $checked ]
 LibTest/isolate/SendPort/call_A01_t01: Fail # Future is in async library. co19 issue 367
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index af31ae0..09f39d0 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -239,6 +239,8 @@
 LibTest/core/RegExp/allMatches_A01_t01: Fail # iterator-change, co19 issue 365
 LibTest/core/Set/Set.from_A01_t02: Fail # iterator-change, co19 issue 365
 
+LibTest/core/Date/operator_equality_A01_t01: Fail # DateTime.== now looks at timezone, co19 issue 379
+
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t01: Fail # issue 6085
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t02: Fail # issue 6085
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t03: Fail # issue 6085
diff --git a/tests/compiler/dart2js_native/native_constructor_name_test.dart b/tests/compiler/dart2js_native/native_constructor_name_test.dart
new file mode 100644
index 0000000..bbf8b5c
--- /dev/null
+++ b/tests/compiler/dart2js_native/native_constructor_name_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test to see if a Dart class name is confused with dispatch tag.  Both class A
+// and class Z have a JavaScript constuctor named "A".  The dynamic native class
+// dispatch hook on Object.prototype should avoid patching the Dart class A.
+// This could be done by renaming the Dart constructor or by being able to check
+// that objects are Dart classes.
+
+class A {
+}
+
+class Z native "*A" {
+  foo() => 100;
+}
+
+makeZ() native;
+
+void setup() native """
+function A(){}
+makeZ = function(){return new A};
+""";
+
+main() {
+  setup();
+
+  var a = new A();
+  var z = makeZ();
+
+  Expect.equals(100, z.foo());
+
+  Expect.throws(() => a.foo(),  (ex) => ex is NoSuchMethodError);
+}
diff --git a/tests/corelib/date_time_test.dart b/tests/corelib/date_time_test.dart
index cceaa1c..6150065 100644
--- a/tests/corelib/date_time_test.dart
+++ b/tests/corelib/date_time_test.dart
@@ -317,13 +317,16 @@
 
   static void testConstructors() {
     var dt0 = new DateTime.utc(2011, 5, 11, 18, 58, 35, 0);
+    var dt0b = new DateTime.utc(2011, 5, 11, 18, 58, 35, 0).toLocal();
     Expect.equals(1305140315000, dt0.millisecondsSinceEpoch);
     var dt1 = new DateTime.fromMillisecondsSinceEpoch(1305140315000);
     Expect.equals(dt1.millisecondsSinceEpoch, dt0.millisecondsSinceEpoch);
-    Expect.equals(true, dt1 == dt0);
+    Expect.equals(false, dt1 == dt0);
+    Expect.equals(true, dt1 == dt0b);
     var dt3 = new DateTime(dt1.year, dt1.month, dt1.day, dt1.hour, dt1.minute,
                        dt1.second, dt1.millisecond);
     Expect.equals(dt1.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
+    Expect.equals(false, dt3 == dt0);
     Expect.equals(true, dt1 == dt3);
     dt3 = new DateTime(
         dt1.year, dt1.month, dt1.day, dt1.hour, dt1.minute,
diff --git a/tests/html/async_window_test.dart b/tests/html/async_window_test.dart
index 1e55448..7410e49 100644
--- a/tests/html/async_window_test.dart
+++ b/tests/html/async_window_test.dart
@@ -2,29 +2,32 @@
 import '../../pkg/unittest/lib/unittest.dart';
 import '../../pkg/unittest/lib/html_config.dart';
 import 'dart:html';
+import 'dart:async';
 
 main() {
   useHtmlConfiguration();
-  test('Window.setTimeout', () {
-    window.setTimeout(expectAsync0((){}), 10);
+  test('Timer', () {
+    new Timer(const Duration(milliseconds: 10), expectAsync0((){}));
   });
-  test('Window.setInterval', () {
+  test('Timer.repeating', () {
     int counter = 0;
     int id = null;
-    id = window.setInterval(expectAsyncUntil0(
-      () {
-        if (counter == 3) {
-          counter = 1024;
-          window.clearInterval(id);
-          // Wait some more time to be sure callback won't be invoked any more.
-          window.setTimeout(expectAsync0((){}), 50);
-          return;
-        }
-        // As callback should have been cleared on 4th invocation, counter
-        // should never be greater than 3.
-        assert(counter < 3);
-        counter++;
-      },
-      () => counter == 3), 10);
+    new Timer.repeating(const Duration(milliseconds: 10),
+        expectAsyncUntil1(
+        (timer) {
+          if (counter == 3) {
+            counter = 1024;
+            timer.cancel();
+            // Wait some more time to be sure callback won't be invoked any
+            // more.
+            new Timer(const Duration(milliseconds: 50), expectAsync0((){}));
+            return;
+          }
+          // As callback should have been cleared on 4th invocation, counter
+          // should never be greater than 3.
+          assert(counter < 3);
+          counter++;
+        },
+        () => counter == 3));
   });
 }
diff --git a/tests/html/cssstyledeclaration_test.dart b/tests/html/cssstyledeclaration_test.dart
index a0ef366..1f86605 100644
--- a/tests/html/cssstyledeclaration_test.dart
+++ b/tests/html/cssstyledeclaration_test.dart
@@ -6,6 +6,7 @@
 import '../../pkg/unittest/lib/unittest.dart';
 import '../../pkg/unittest/lib/html_config.dart';
 import 'dart:html';
+import 'dart:async';
 
 main() {
   useHtmlConfiguration();
@@ -84,10 +85,10 @@
     document.body.children.add(element);
 
     // Need to wait one tick after the element has been added to the page.
-    window.setTimeout(expectAsync0(() {
+    new Timer(const Duration(milliseconds: 10), expectAsync0(() {
       element.style.textDecoration = 'underline';
       var style = element.getComputedStyle();
       expect(style.textDecoration, equals('underline'));
-    }), 10);
+    }));
   });
 }
diff --git a/tests/html/dromaeo_noop/dromaeo_smoke.dart b/tests/html/dromaeo_noop/dromaeo_smoke.dart
index fbae236..4dd24f2 100644
--- a/tests/html/dromaeo_noop/dromaeo_smoke.dart
+++ b/tests/html/dromaeo_noop/dromaeo_smoke.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library dromaeo;
+import 'dart:async';
 import 'dart:html';
 import 'dart:json' as json;
 import '../../../samples/third_party/dromaeo/common/common.dart';
diff --git a/tests/html/element_test.dart b/tests/html/element_test.dart
index d838efa..680face 100644
--- a/tests/html/element_test.dart
+++ b/tests/html/element_test.dart
@@ -298,23 +298,23 @@
         expect(attributes['data-foo'], 'bar');
         expect(attributes['data-foo2'], 'bar2');
         expect(attributes.length, 5);
-        expect(element.dataAttributes.length, 2);
-        element.dataAttributes['foo'] = 'baz';
-        expect(element.dataAttributes['foo'], 'baz');
+        expect(element.dataset.length, 2);
+        element.dataset['foo'] = 'baz';
+        expect(element.dataset['foo'], 'baz');
         expect(attributes['data-foo'], 'baz');
         attributes['data-foo2'] = 'baz2';
         expect(attributes['data-foo2'], 'baz2');
-        expect(element.dataAttributes['foo2'], 'baz2');
+        expect(element.dataset['foo2'], 'baz2');
         expect(attributes['dir'], 'rtl');
 
-        final dataAttributes = element.dataAttributes;
-        dataAttributes.remove('foo2');
+        final dataset = element.dataset;
+        dataset.remove('foo2');
         expect(attributes.length, 4);
-        expect(dataAttributes.length, 1);
+        expect(dataset.length, 1);
         attributes.remove('style');
         expect(attributes.length, 3);
-        dataAttributes['foo3'] = 'baz3';
-        expect(dataAttributes.length, 2);
+        dataset['foo3'] = 'baz3';
+        expect(dataset.length, 2);
         expect(attributes.length, 4);
         attributes['style'] = 'width: 300px;';
         expect(attributes.length, 5);
diff --git a/tests/html/form_data_test.dart b/tests/html/form_data_test.dart
index 0ddd97d..75dedce 100644
--- a/tests/html/form_data_test.dart
+++ b/tests/html/form_data_test.dart
@@ -5,8 +5,9 @@
 library FormDataTest;
 
 import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import '../../pkg/unittest/lib/html_individual_config.dart';
 import 'dart:html';
+import 'dart:uri';
 
 void fail(message) {
   guardAsync(() {
@@ -17,56 +18,75 @@
 void main() {
   // TODO(efortuna): This is a bad test. Revisit when we have tests that can run
   // both a server and fire up a browser.
-  useHtmlConfiguration();
+  useHtmlIndividualConfiguration();
 
-  var isFormData = predicate((x) => x is FormData, 'is a FormData');
-
-  test('constructorTest1', () {
-    var form = new FormData();
-    expect(form, isNotNull);
-    expect(form, isFormData);
-  });
-
-  test('constructorTest2', () {
-    var form = new FormData(new FormElement());
-    expect(form, isNotNull);
-    expect(form, isFormData);
-  });
-
-  test('appendTest', () {
-    var form = new FormData();
-    form.append('test', '1');
-    form.append('username', 'Elmo');
-    form.append('address', '1 Sesame Street');
-    form.append('password', '123456', 'foo');
-    expect(form, isNotNull);
-  });
-
-  test('appendBlob', () {
-    var form = new FormData();
-    var blob = new Blob(
-        ['Indescribable... Indestructible! Nothing can stop it!'],
-        'text/plain');
-    form.append('theBlob', blob, 'theBlob.txt');
-  });
-
-  test('send', () {
-    var form = new FormData();
-    var blobString = 'Indescribable... Indestructible! Nothing can stop it!';
-    var blob = new Blob(
-        [blobString],
-        'text/plain');
-    form.append('theBlob', blob, 'theBlob.txt');
-
-    var xhr = new HttpRequest();
-    xhr.open("POST", "http://localhost:${window.location.port}/echo");
-
-    xhr.onLoad.listen(expectAsync1((e) {
-      expect(xhr.responseText.contains(blobString), true);
-    }));
-    xhr.onError.listen((e) {
-      fail('$e');
+  group('supported', () {
+    test('supported', () {
+      expect(FormData.supported, isTrue);
     });
-    xhr.send(form);
+  });
+
+  group('functional', () {
+    test('unsupported throws', () {
+      var expectation = FormData.supported ? returnsNormally : throws;
+      expect(() {
+        new FormData();
+      }, expectation);
+    });
+
+    var isFormData = predicate((x) => x is FormData, 'is a FormData');
+
+    if (FormData.supported) {
+      test('constructorTest1', () {
+        var form = new FormData();
+        expect(form, isNotNull);
+        expect(form, isFormData);
+      });
+
+      test('constructorTest2', () {
+        var form = new FormData(new FormElement());
+        expect(form, isNotNull);
+        expect(form, isFormData);
+      });
+
+      test('appendTest', () {
+        var form = new FormData();
+        form.append('test', '1');
+        form.append('username', 'Elmo');
+        form.append('address', '1 Sesame Street');
+        form.append('password', '123456', 'foo');
+        expect(form, isNotNull);
+      });
+
+      test('appendBlob', () {
+        var form = new FormData();
+        var blob = new Blob(
+            ['Indescribable... Indestructible! Nothing can stop it!'],
+            'text/plain');
+        form.append('theBlob', blob, 'theBlob.txt');
+      });
+
+      test('send', () {
+        var form = new FormData();
+        var blobString =
+            'Indescribable... Indestructible! Nothing can stop it!';
+        var blob = new Blob(
+            [blobString],
+            'text/plain');
+        form.append('theBlob', blob, 'theBlob.txt');
+
+        var xhr = new HttpRequest();
+        xhr.open('POST',
+            '${window.location.protocol}//${window.location.host}/echo');
+
+        xhr.onLoad.listen(expectAsync1((e) {
+          expect(xhr.responseText.contains(blobString), true);
+        }));
+        xhr.onError.listen((e) {
+          fail('$e');
+        });
+        xhr.send(form);
+      });
+    }
   });
 }
diff --git a/tests/html/history_test.dart b/tests/html/history_test.dart
index f2c7c12..7ee08ce 100644
--- a/tests/html/history_test.dart
+++ b/tests/html/history_test.dart
@@ -2,6 +2,7 @@
 import '../../pkg/unittest/lib/unittest.dart';
 import '../../pkg/unittest/lib/html_individual_config.dart';
 import 'dart:html';
+import 'dart:async';
 
 main() {
   useHtmlIndividualConfiguration();
@@ -42,14 +43,14 @@
         expect(window.location.href.endsWith('dummy2'), isTrue);
 
         // Need to wait a frame or two to let the pushState events occur.
-        window.setTimeout(expectAsync0(() {
+        new Timer(const Duration(milliseconds: 100), expectAsync0(() {
           window.onPopState.first.then(expectAsync1((_){
             expect(window.history.length, length);
             expect(window.location.href.endsWith('dummy1'), isTrue);
           }));
 
           window.history.back();
-        }), 100);
+        }));
       }, expectation);
     });
 
diff --git a/tests/html/html.status b/tests/html/html.status
index 6f2c417..0596b92 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -63,7 +63,6 @@
 element_types_test/supported_meter: Fail
 element_types_test/supported_output: Fail
 element_types_test/supported_shadow: Fail
-form_data_test: Fail # TODO(efortuna): Issue 7875.
 fileapi_test/supported: Fail
 history_test/supported_HashChangeEvent: Fail
 inner_frame_test: Skip
@@ -117,7 +116,7 @@
 element_types_test/supported_progress: Fail
 element_types_test/supported_shadow: Fail
 element_types_test/supported_track: Fail
-form_data_test: Fail # Issue 4793.
+form_data_test/supported: Fail
 form_element_test: Fail # Issue 4793.
 inner_frame_test: Skip # Issue 5727 (timeout)
 transition_event_test/supported: Fail
@@ -201,8 +200,9 @@
 websocket_test/supported: Fail
 window_open_test: Skip      # BUG(4016)
 isolates_test: Skip         # BUG(4016)
-xhr_test: Skip              # BUG(4016)
 xhr_test/supported_HttpRequestProgressEvent: Fail
+xhr_test/supported_onLoadEnd: Fail
+xhr_test/supported_onProgress: Fail
 xhr_cross_origin_test: Fail # Issue 6016.
 xsltprocessor_test/supported: Fail
 
diff --git a/tests/html/htmlelement_test.dart b/tests/html/htmlelement_test.dart
index 7c5e5a0..c18ba67 100644
--- a/tests/html/htmlelement_test.dart
+++ b/tests/html/htmlelement_test.dart
@@ -29,21 +29,21 @@
     TableRowElement headerRow = table.rows[0];
     expect(headerRow.cells.length, 2);
   });
-  test('dataAttributes', () {
+  test('dataset', () {
     Element div = new Element.tag('div');
 
-    expect(div.dataAttributes.isEmpty, isTrue);
-    expect(div.dataAttributes['foo'], isNull);
-    expect(div.dataAttributes.isEmpty, isTrue);
+    expect(div.dataset.isEmpty, isTrue);
+    expect(div.dataset['foo'], isNull);
+    expect(div.dataset.isEmpty, isTrue);
 
-    div.dataAttributes['foo'] = 'foo-value';
-    expect(div.dataAttributes['foo'], 'foo-value');
-    expect(div.dataAttributes.isEmpty, isFalse);
+    div.dataset['foo'] = 'foo-value';
+    expect(div.dataset['foo'], 'foo-value');
+    expect(div.dataset.isEmpty, isFalse);
 
-    expect(div.dataAttributes.containsValue('foo-value'), isTrue);
-    expect(div.dataAttributes.containsValue('bar-value'), isFalse);
-    expect(div.dataAttributes.containsKey('foo'), isTrue);
-    expect(div.dataAttributes.containsKey('bar'), isFalse);
+    expect(div.dataset.containsValue('foo-value'), isTrue);
+    expect(div.dataset.containsValue('bar-value'), isFalse);
+    expect(div.dataset.containsKey('foo'), isTrue);
+    expect(div.dataset.containsKey('bar'), isFalse);
 
     bool hasBeenInvoked;
     String f() {
@@ -52,40 +52,40 @@
     }
 
     hasBeenInvoked = false;
-    expect(div.dataAttributes.putIfAbsent('bar', f), 'bar-value');
+    expect(div.dataset.putIfAbsent('bar', f), 'bar-value');
     expect(hasBeenInvoked, isTrue);
 
     hasBeenInvoked = false;
-    expect(div.dataAttributes.putIfAbsent('bar', f), 'bar-value');
+    expect(div.dataset.putIfAbsent('bar', f), 'bar-value');
     expect(hasBeenInvoked, isFalse);
 
     final keys = <String> [];
     final values = <String> [];
-    div.dataAttributes.forEach((String key, String value) {
+    div.dataset.forEach((String key, String value) {
         keys.add(key);
         values.add(value);
     });
     expect(keys, unorderedEquals(['foo', 'bar']));
     expect(values, unorderedEquals(['foo-value', 'bar-value']));
 
-    expect(new List<String>.from(div.dataAttributes.keys),
+    expect(new List<String>.from(div.dataset.keys),
         unorderedEquals(['foo', 'bar']));
-    expect(new List<String>.from(div.dataAttributes.values),
+    expect(new List<String>.from(div.dataset.values),
         unorderedEquals(['foo-value', 'bar-value']));
 
-    expect(div.dataAttributes.length, 2);
-    expect(div.dataAttributes.isEmpty, isFalse);
+    expect(div.dataset.length, 2);
+    expect(div.dataset.isEmpty, isFalse);
 
-    expect(div.dataAttributes.remove('qux'), isNull);
-    expect(div.dataAttributes.length, 2);
-    expect(div.dataAttributes.isEmpty, isFalse);
+    expect(div.dataset.remove('qux'), isNull);
+    expect(div.dataset.length, 2);
+    expect(div.dataset.isEmpty, isFalse);
 
-    expect(div.dataAttributes.remove('foo'), 'foo-value');
-    expect(div.dataAttributes.length, 1);
-    expect(div.dataAttributes.isEmpty, isFalse);
+    expect(div.dataset.remove('foo'), 'foo-value');
+    expect(div.dataset.length, 1);
+    expect(div.dataset.isEmpty, isFalse);
 
-    div.dataAttributes.clear();
-    expect(div.dataAttributes.length, 0);
-    expect(div.dataAttributes.isEmpty, isTrue);
+    div.dataset.clear();
+    expect(div.dataset.length, 0);
+    expect(div.dataset.isEmpty, isTrue);
   });
 }
diff --git a/tests/html/js_interop_3_test.dart b/tests/html/js_interop_3_test.dart
index 142c4d9..390c687 100644
--- a/tests/html/js_interop_3_test.dart
+++ b/tests/html/js_interop_3_test.dart
@@ -5,6 +5,7 @@
 library JsInterop3Test;
 import '../../pkg/unittest/lib/unittest.dart';
 import '../../pkg/unittest/lib/html_config.dart';
+import 'dart:async';
 import 'dart:html';
 import 'dart:isolate';
 
@@ -43,7 +44,7 @@
     var done = expectAsync0(() {});
     var fun2 = (message) {
       expect(message, 42);
-      window.setTimeout(done, 0);
+      Timer.run(done);
     };
 
     var port2 = new ReceivePortSync();
diff --git a/tests/html/js_interop_4_test.dart b/tests/html/js_interop_4_test.dart
index 935c790..944506b 100644
--- a/tests/html/js_interop_4_test.dart
+++ b/tests/html/js_interop_4_test.dart
@@ -5,6 +5,7 @@
 library JsInterop4Test;
 import '../../pkg/unittest/lib/unittest.dart';
 import '../../pkg/unittest/lib/html_config.dart';
+import 'dart:async';
 import 'dart:html';
 import 'dart:isolate';
 
@@ -52,7 +53,7 @@
     var done = expectAsync0(() {});
     var fun2 = (message) {
       expect(message, 3);
-      window.setTimeout(done, 0);
+      Timer.run(done);
     };
 
     var port2 = new ReceivePortSync();
diff --git a/tests/html/microtask_test.dart b/tests/html/microtask_test.dart
index 0dfcc53..79adb28 100644
--- a/tests/html/microtask_test.dart
+++ b/tests/html/microtask_test.dart
@@ -5,6 +5,7 @@
 library microtask_;
 import '../../pkg/unittest/lib/unittest.dart';
 import '../../pkg/unittest/lib/html_config.dart';
+import 'dart:async';
 import 'dart:html';
 
 main() {
@@ -15,10 +16,10 @@
     var rafCalled = false;
     var immediateCalled = false;
 
-    window.setTimeout(expectAsync0(() {
+    Timer.run(expectAsync0(() {
       timeoutCalled = true;
       expect(immediateCalled, true);
-    }), 0);
+    }));
 
 
     window.requestAnimationFrame((_) {
diff --git a/tests/html/node_test.dart b/tests/html/node_test.dart
index d9cfe24..fe31ed7 100644
--- a/tests/html/node_test.dart
+++ b/tests/html/node_test.dart
@@ -159,6 +159,23 @@
       expect(node.nodes[3], isHRElement);
       expect(node.nodes[4], isImageElement);
       expect(node.nodes[5], isInputElement);
+
+      var a = makeNodeWithChildren();
+      var b = makeNodeWithChildren();
+      var childrenLength = a.children.length + b.children.length;
+      var nodesLength = a.nodes.length + b.nodes.length;
+
+      a.children.addAll(b.children);
+      expect(b.children.length, 0);
+      expect(a.children.length, childrenLength);
+
+      b.nodes.addAll(a.children);
+      expect(a.children.length, 0);
+      expect(b.children.length, childrenLength);
+
+      a.nodes.addAll(b.nodes);
+      expect(b.nodes.length, 0);
+      expect(a.nodes.length, nodesLength);
     });
 
     test('clear', () {
diff --git a/tests/html/streams_test.dart b/tests/html/streams_test.dart
index 6c75dfe..8a46b65 100644
--- a/tests/html/streams_test.dart
+++ b/tests/html/streams_test.dart
@@ -36,6 +36,12 @@
     expect(callCount, 1);
   });
 
+  test('broadcast', () {
+    var stream = new DivElement().onClick;
+    expect(stream.asBroadcastStream(), stream);
+    expect(stream.isBroadcast, isTrue);
+  });
+
   // Validates that capturing events fire on parent before child.
   test('capture', () {
     var parent = new DivElement();
diff --git a/tests/html/transition_event_test.dart b/tests/html/transition_event_test.dart
index c96b46b..8e04110 100644
--- a/tests/html/transition_event_test.dart
+++ b/tests/html/transition_event_test.dart
@@ -6,6 +6,7 @@
 import '../../pkg/unittest/lib/unittest.dart';
 import '../../pkg/unittest/lib/html_individual_config.dart';
 import 'dart:html';
+import 'dart:async';
 
 main() {
   useHtmlIndividualConfiguration();
@@ -28,14 +29,14 @@
         element.style.background = 'red';
         element.style.transition = 'opacity .1s';
 
-        window.setTimeout(expectAsync0(() {
+        new Timer(const Duration(milliseconds: 100), expectAsync0(() {
           element.onTransitionEnd.first.then(expectAsync1((e) {
             expect(e is TransitionEvent, isTrue);
             expect(e.propertyName, 'opacity');
           }));
 
           element.style.opacity = '1';
-        }), 100);
+        }));
       }
     });
   });
diff --git a/tests/html/window_open_test.dart b/tests/html/window_open_test.dart
index 8fbe664..23baef4 100644
--- a/tests/html/window_open_test.dart
+++ b/tests/html/window_open_test.dart
@@ -2,6 +2,7 @@
 import '../../pkg/unittest/lib/unittest.dart';
 import '../../pkg/unittest/lib/html_config.dart';
 import 'dart:html';
+import 'dart:async';
 
 main() {
   useHtmlConfiguration();
@@ -26,8 +27,8 @@
   win.close();
   doneHandler() {
     if (!win.closed) {
-      window.setTimeout(expectAsync0(doneHandler), 1);
+      new Timer(const Duration(milliseconds: 1), expectAsync0(doneHandler));
     }
   }
-  window.setTimeout(expectAsync0(doneHandler), 1);
+  new Timer(const Duration(milliseconds: 1), expectAsync0(doneHandler));
 }
diff --git a/tests/html/xhr_test.dart b/tests/html/xhr_test.dart
index d590ace..6c8393c 100644
--- a/tests/html/xhr_test.dart
+++ b/tests/html/xhr_test.dart
@@ -5,6 +5,7 @@
 library XHRTest;
 import '../../pkg/unittest/lib/unittest.dart';
 import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'dart:async';
 import 'dart:html';
 import 'dart:json' as json;
 
@@ -20,7 +21,7 @@
 
   void validate200Response(xhr) {
     expect(xhr.status, equals(200));
-    var data = json.parse(xhr.response);
+    var data = json.parse(xhr.responseText);
     expect(data, contains('feed'));
     expect(data['feed'], contains('entry'));
     expect(data, isMap);
@@ -37,6 +38,18 @@
     });
   });
 
+  group('supported_onProgress', () {
+    test('supported', () {
+      expect(HttpRequest.supportsProgressEvent, isTrue);
+    });
+  });
+
+  group('supported_onLoadEnd', () {
+    test('supported', () {
+      expect(HttpRequest.supportsLoadEndEvent, isTrue);
+    });
+  });
+
   group('xhr', () {
     test('XHR No file', () {
       HttpRequest xhr = new HttpRequest();
@@ -50,18 +63,23 @@
     });
 
     test('XHR file', () {
+      var loadEndCalled = false;
+
       var xhr = new HttpRequest();
       xhr.open('GET', url, true);
       xhr.onReadyStateChange.listen(expectAsyncUntil1((e) {
         if (xhr.readyState == HttpRequest.DONE) {
           validate200Response(xhr);
+
+          Timer.run(expectAsync0(() {
+            expect(loadEndCalled, HttpRequest.supportsLoadEndEvent);
+          }));
         }
       }, () => xhr.readyState == HttpRequest.DONE));
 
-      xhr.onLoadEnd.listen(expectAsync1((ProgressEvent e) {
-        expect(e.currentTarget, xhr);
-        expect(e.target, xhr);
-      }));
+      xhr.onLoadEnd.listen((ProgressEvent e) {
+        loadEndCalled = true;
+      });
       xhr.send();
     });
 
@@ -90,7 +108,7 @@
         }).then(expectAsync1(
           (xhr) {
             expect(xhr.readyState, equals(HttpRequest.DONE));
-            expect(progressCalled, isTrue);
+            expect(progressCalled, HttpRequest.supportsProgressEvent);
             validate200Response(xhr);
           }));
     });
diff --git a/tools/VERSION b/tools/VERSION
index 05b0467..9fbcad9 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
 MINOR 3
-BUILD 6
-PATCH 2
+BUILD 7
+PATCH 0
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index 12d22c0..0fc3789 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -737,6 +737,7 @@
     "@SupportedBrowser(SupportedBrowser.CHROME, '25')",
     "@Experimental",
   ],
+  'FormData': _all_but_ie9_annotations,
   'HashChangeEvent': [
     "@SupportedBrowser(SupportedBrowser.CHROME)",
     "@SupportedBrowser(SupportedBrowser.FIREFOX)",
@@ -844,6 +845,9 @@
   'WorkerContext.webkitRequestFileSystemSync': _file_system_annotations,
   'WorkerContext.webkitResolveLocalFileSystemSyncURL': _file_system_annotations,
   'WorkerContext.webkitResolveLocalFileSystemURL': _file_system_annotations,
+  'XMLHttpRequest.onloadend': _all_but_ie9_annotations,
+  'XMLHttpRequest.onprogress': _all_but_ie9_annotations,
+  'XMLHttpRequest.response': _all_but_ie9_annotations,
   'XMLHttpRequestProgressEvent': _webkit_experimental_annotations,
   'XSLTProcessor': [
     "@SupportedBrowser(SupportedBrowser.CHROME)",
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index 2057291..32bb712 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -194,6 +194,10 @@
     'Document.defaultView': 'window',
     'DOMURL.createObjectURL': 'createObjectUrl',
     'DOMURL.revokeObjectURL': 'revokeObjectUrl',
+    'DOMWindow.clearTimeout': '_clearTimeout',
+    'DOMWindow.clearInterval': '_clearInterval',
+    'DOMWindow.setTimeout': '_setTimeout',
+    'DOMWindow.setInterval': '_setInterval',
     'DOMWindow.webkitConvertPointFromNodeToPage': 'convertPointFromNodeToPage',
     'DOMWindow.webkitConvertPointFromPageToNode': 'convertPointFromPageToNode',
     'DOMWindow.webkitNotifications': 'notifications',
@@ -332,6 +336,7 @@
     'DOMCoreException.VALIDATION_ERR',
     'DOMCoreException.WRONG_DOCUMENT_ERR',
     'Element.accessKey',
+    'Element.dataset',
     'Element.get:classList',
     'Element.getAttributeNode',
     'Element.getAttributeNodeNS',
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 2594b1e..0ef461e 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -356,6 +356,7 @@
     'Database': "JS('bool', '!!(window.openDatabase)')",
     'DOMApplicationCache': "JS('bool', '!!(window.applicationCache)')",
     'DOMFileSystem': "JS('bool', '!!(window.webkitRequestFileSystem)')",
+    'FormData': "JS('bool', '!!(window.FormData)')",
     'HashChangeEvent': "Event._isTypeSupported('HashChangeEvent')",
     'HTMLShadowElement': ElemSupportStr('shadow'),
     'MediaStreamEvent': "Event._isTypeSupported('MediaStreamEvent')",
diff --git a/tools/dom/src/EventStreamProvider.dart b/tools/dom/src/EventStreamProvider.dart
index 2dd9560..a74e998 100644
--- a/tools/dom/src/EventStreamProvider.dart
+++ b/tools/dom/src/EventStreamProvider.dart
@@ -16,6 +16,7 @@
 
   // DOM events are inherently multi-subscribers.
   Stream<T> asBroadcastStream() => this;
+  bool get isBroadcast => true;
 
   StreamSubscription<T> listen(void onData(T event),
       { void onError(AsyncError error),
diff --git a/tools/dom/src/Timer.dart b/tools/dom/src/Timer.dart
index 91ad281..01048ea 100644
--- a/tools/dom/src/Timer.dart
+++ b/tools/dom/src/Timer.dart
@@ -17,11 +17,11 @@
   var maker;
   var canceller;
   if (repeating) {
-    maker = window.setInterval;
-    canceller = window.clearInterval;
+    maker = window._setInterval;
+    canceller = window._clearInterval;
   } else {
-    maker = window.setTimeout;
-    canceller = window.clearTimeout;
+    maker = window._setTimeout;
+    canceller = window._clearTimeout;
   }
   Timer timer;
   final int id = maker(() { callback(timer); }, milliSeconds);
diff --git a/tools/dom/templates/html/dartium/impl_Window.darttemplate b/tools/dom/templates/html/dartium/impl_Window.darttemplate
deleted file mode 100644
index 3c4125b..0000000
--- a/tools/dom/templates/html/dartium/impl_Window.darttemplate
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of $LIBRARYNAME;
-
-$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
-
-  /**
-   * Executes a [callback] after the immediate execution stack has completed.
-   *
-   * This will cause the callback to be executed after all processing has
-   * completed for the current event, but before any subsequent events.
-   */
-  void setImmediate(TimeoutHandler callback) {
-    _addMicrotaskCallback(callback);
-  }
-
-  /**
-   * Lookup a port by its [name].  Return null if no port is
-   * registered under [name].
-   */
-  lookupPort(String name) {
-    var port = json.parse(document.documentElement.attributes['dart-port:$name']);
-    return _deserialize(port);
-  }
-
-  /**
-   * Register a [port] on this window under the given [name].  This
-   * port may be retrieved by any isolate (or JavaScript script)
-   * running in this window.
-   */
-  registerPort(String name, var port) {
-    var serialized = _serialize(port);
-    document.documentElement.attributes['dart-port:$name'] = json.stringify(serialized);
-  }
-
-  /// Checks if _setImmediate is supported.
-  static bool get _supportsSetImmediate => false;
-
-  /// Dartium stub for IE's setImmediate.
-  void _setImmediate(void callback()) {
-    throw new UnsupportedError('setImmediate is not supported');
-  }
-
-$!MEMBERS
-}
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 5499b22..791b1ab 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -140,6 +140,10 @@
   Iterator<Element> get iterator => toList().iterator;
 
   void addAll(Iterable<Element> iterable) {
+    if (iterable is _ChildNodeListLazy) {
+      iterable = new List.from(iterable);
+    }
+
     for (Element element in iterable) {
       _element.$dom_appendChild(element);
     }
@@ -669,20 +673,20 @@
    *
    * Would be accessed in Dart as:
    *
-   *     var value = element.dataAttributes['myRandomValue'];
+   *     var value = element.dataset['myRandomValue'];
    *
    * See also:
    *
    * * [Custom data attributes](http://www.w3.org/TR/html5/global-attributes.html#custom-data-attribute)
    */
-  Map<String, String> get dataAttributes =>
+  Map<String, String> get dataset =>
     new _DataAttributeMap(attributes);
 
-  void set dataAttributes(Map<String, String> value) {
-    final dataAttributes = this.dataAttributes;
-    dataAttributes.clear();
+  void set dataset(Map<String, String> value) {
+    final data = this.dataset;
+    data.clear();
     for (String key in value.keys) {
-      dataAttributes[key] = value[key];
+      data[key] = value[key];
     }
   }
 
diff --git a/tools/dom/templates/html/impl/impl_Node.darttemplate b/tools/dom/templates/html/impl/impl_Node.darttemplate
index f407ee7..ceeb922 100644
--- a/tools/dom/templates/html/impl/impl_Node.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Node.darttemplate
@@ -69,6 +69,9 @@
 
 
   void addAll(Iterable<Node> iterable) {
+    if (iterable is _ChildNodeListLazy) {
+      iterable = new List.from(iterable);
+    }
     for (Node node in iterable) {
       _this.$dom_appendChild(node);
     }
diff --git a/tools/dom/templates/html/dart2js/impl_Window.darttemplate b/tools/dom/templates/html/impl/impl_Window.darttemplate
similarity index 71%
rename from tools/dom/templates/html/dart2js/impl_Window.darttemplate
rename to tools/dom/templates/html/impl/impl_Window.darttemplate
index 1f74f22..083aebd 100644
--- a/tools/dom/templates/html/dart2js/impl_Window.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Window.darttemplate
@@ -4,8 +4,63 @@
 
 part of $LIBRARYNAME;
 
+$if DART2JS
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS native "@*DOMWindow" {
+$else
+$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
+$endif
 
+  /**
+   * Executes a [callback] after the immediate execution stack has completed.
+   *
+   * This differs from using Timer.run(callback)
+   * because Timer will run in about 4-15 milliseconds, depending on browser,
+   * depending on load. [setImmediate], in contrast, makes browser-specific
+   * changes in behavior to attempt to run immediately after the current
+   * frame unwinds, causing the future to complete after all processing has
+   * completed for the current event, but before any subsequent events.
+   */
+  void setImmediate(TimeoutHandler callback) { 
+    _addMicrotaskCallback(callback);
+  }
+  /**
+   * Lookup a port by its [name].  Return null if no port is
+   * registered under [name].
+   */
+  SendPortSync lookupPort(String name) {
+    var port =
+        json.parse(document.documentElement.attributes['dart-port:$name']);
+    return _deserialize(port);
+  }
+
+  /**
+   * Register a [port] on this window under the given [name].  This
+   * port may be retrieved by any isolate (or JavaScript script)
+   * running in this window.
+   */
+  void registerPort(String name, var port) {
+    var serialized = _serialize(port);
+    document.documentElement.attributes['dart-port:$name'] =
+        json.stringify(serialized);
+  }
+
+  /**
+   * Returns a Future that completes just before the window is about to repaint
+   * so the user can draw an animation frame
+   *
+   * If you need to later cancel this animation, use [requestAnimationFrame]
+   * instead.
+   *
+   * Note: The code that runs when the future completes should call 
+   * [animationFrame] again for the animation to continue.
+   */
+  Future<num> get animationFrame {
+    var completer = new Completer<int>();
+    requestAnimationFrame(completer.complete);
+    return completer.future;
+  }
+
+$if DART2JS
   Document get document => JS('Document', '#.document', this);
 
   WindowBase _open2(url, name) => JS('Window', '#.open(#,#)', this, url, name);
@@ -71,15 +126,21 @@
   }
 
   /**
-   * Executes a [callback] after the immediate execution stack has completed.
+   * Called to draw an animation frame and then request the window to repaint
+   * after [callback] has finished (creating the animation). 
    *
-   * This will cause the callback to be executed after all processing has
-   * completed for the current event, but before any subsequent events.
+   * Use this method only if you need to later call [cancelAnimationFrame]. If
+   * not, the preferred Dart idiom is to set animation frames by calling
+   * [animationFrame], which returns a Future.
+   *
+   * Returns a non-zero valued integer to represent the request id for this
+   * request. This value only needs to be saved if you intend to call
+   * [cancelAnimationFrame] so you can specify the particular animation to
+   * cancel.
+   *
+   * Note: The supplied [callback] needs to call [requestAnimationFrame] again
+   * for the animation to continue.
    */
-  void setImmediate(TimeoutHandler callback) {
-    _addMicrotaskCallback(callback);
-  }
-
   @DomName('DOMWindow.requestAnimationFrame')
   int requestAnimationFrame(RequestAnimationFrameCallback callback) {
     _ensureRequestAnimationFrame();
@@ -138,25 +199,6 @@
          '#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB',
          this, this, this);
 
-  /**
-   * Lookup a port by its [name].  Return null if no port is
-   * registered under [name].
-   */
-  SendPortSync lookupPort(String name) {
-    var port = json.parse(document.documentElement.attributes['dart-port:$name']);
-    return _deserialize(port);
-  }
-
-  /**
-   * Register a [port] on this window under the given [name].  This
-   * port may be retrieved by any isolate (or JavaScript script)
-   * running in this window.
-   */
-  void registerPort(String name, var port) {
-    var serialized = _serialize(port);
-    document.documentElement.attributes['dart-port:$name'] = json.stringify(serialized);
-  }
-
   @DomName('Window.console')
   Console get console => Console.safeConsole;
 
@@ -168,6 +210,15 @@
   void _setImmediate(void callback()) {
     JS('void', '#.setImmediate(#)', this, convertDartClosureToJS(callback, 0));
   }
+$else
+  /// Checks if _setImmediate is supported.
+  static bool get _supportsSetImmediate => false;
+
+  /// Dartium stub for IE's setImmediate.
+  void _setImmediate(void callback()) {
+    throw new UnsupportedError('setImmediate is not supported');
+  }
+$endif
 
 $!MEMBERS
 }
diff --git a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
index 1b75464..cc8eef3 100644
--- a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
+++ b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
@@ -122,5 +122,29 @@
     return completer.future;
   }
 
+  /**
+   * Checks to see if the Progress event is supported on the current platform.
+   */
+  static bool get supportsProgressEvent {
+$if DART2JS
+    var xhr = new HttpRequest();
+    return JS('bool', '"onprogress" in #', xhr);
+$else
+    return true;
+$endif
+  }
+
+  /**
+   * Checks to see if the LoadEnd event is supported on the current platform.
+   */
+  static bool get supportsLoadEndEvent {
+$if DART2JS
+    var xhr = new HttpRequest();
+    return JS('bool', '"onloadend" in #', xhr);
+$else
+    return true;
+$endif
+  }
+
 $!MEMBERS
 }
diff --git a/utils/pub/command_lish.dart b/utils/pub/command_lish.dart
index f2e5f05..d2a033b 100644
--- a/utils/pub/command_lish.dart
+++ b/utils/pub/command_lish.dart
@@ -136,7 +136,7 @@
     var rootDir = entrypoint.root.dir;
 
     return git.isInstalled.then((gitInstalled) {
-      if (dirExists(join(rootDir, '.git')) && gitInstalled) {
+      if (dirExists(path.join(rootDir, '.git')) && gitInstalled) {
         // List all files that aren't gitignored, including those not checked
         // in to Git.
         return git.run(["ls-files", "--cached", "--others",
diff --git a/utils/pub/entrypoint.dart b/utils/pub/entrypoint.dart
index f778bbb..054541d 100644
--- a/utils/pub/entrypoint.dart
+++ b/utils/pub/entrypoint.dart
@@ -53,7 +53,7 @@
 
   // TODO(rnystrom): Make this path configurable.
   /// The path to the entrypoint's "packages" directory.
-  String get packagesDir => join(root.dir, 'packages');
+  String get packagesDir => path.join(root.dir, 'packages');
 
   /// Ensures that the package identified by [id] is installed to the directory.
   /// Returns the resolved [PackageId].
@@ -70,7 +70,7 @@
     var pendingOrCompleted = _installs[id];
     if (pendingOrCompleted != null) return pendingOrCompleted;
 
-    var packageDir = join(packagesDir, id.name);
+    var packageDir = path.join(packagesDir, id.name);
     var future = defer(() {
       ensureDir(path.dirname(packageDir));
       if (!dirExists(packageDir)) return;
@@ -207,7 +207,7 @@
   /// Loads the list of concrete package versions from the `pubspec.lock`, if it
   /// exists. If it doesn't, this completes to an empty [LockFile].
   LockFile loadLockFile() {
-    var lockFilePath = join(root.dir, 'pubspec.lock');
+    var lockFilePath = path.join(root.dir, 'pubspec.lock');
     if (!fileExists(lockFilePath)) return new LockFile.empty();
     return new LockFile.parse(readTextFile(lockFilePath), cache.sources);
   }
@@ -219,7 +219,7 @@
       if (!id.isRoot) lockFile.packages[id.name] = id;
     }
 
-    var lockFilePath = join(root.dir, 'pubspec.lock');
+    var lockFilePath = path.join(root.dir, 'pubspec.lock');
     writeTextFile(lockFilePath, lockFile.serialize());
   }
 
@@ -227,7 +227,7 @@
   /// allow a package to import its own files using `package:`.
   Future _installSelfReference(_) {
     return defer(() {
-      var linkPath = join(packagesDir, root.name);
+      var linkPath = path.join(packagesDir, root.name);
       // Create the symlink if it doesn't exist.
       if (entryExists(linkPath)) return;
       ensureDir(packagesDir);
@@ -240,11 +240,11 @@
   /// into them so that their entrypoints can be run. Do the same for any
   /// subdirectories of `test/` and `example/`.
   Future _linkSecondaryPackageDirs(_) {
-    var binDir = join(root.dir, 'bin');
-    var exampleDir = join(root.dir, 'example');
-    var testDir = join(root.dir, 'test');
-    var toolDir = join(root.dir, 'tool');
-    var webDir = join(root.dir, 'web');
+    var binDir = path.join(root.dir, 'bin');
+    var exampleDir = path.join(root.dir, 'example');
+    var testDir = path.join(root.dir, 'test');
+    var toolDir = path.join(root.dir, 'tool');
+    var webDir = path.join(root.dir, 'web');
     return defer(() {
       if (!dirExists(binDir)) return;
       return _linkSecondaryPackageDir(binDir);
@@ -294,7 +294,7 @@
   /// Creates a symlink to the `packages` directory in [dir] if none exists.
   Future _linkSecondaryPackageDir(String dir) {
     return defer(() {
-      var to = join(dir, 'packages');
+      var to = path.join(dir, 'packages');
       if (entryExists(to)) return;
       return createSymlink(packagesDir, to);
     });
diff --git a/utils/pub/git.dart b/utils/pub/git.dart
index 47519c2..53ecbe7 100644
--- a/utils/pub/git.dart
+++ b/utils/pub/git.dart
@@ -28,8 +28,8 @@
         environment: environment);
   }).then((result) {
     if (!result.success) throw new Exception(
-        'Git error. Command: git ${Strings.join(args, " ")}\n'
-        '${Strings.join(result.stderr, "\n")}');
+        'Git error. Command: git ${args.join(" ")}\n'
+        '${result.stderr.join("\n")}');
 
     return result.stdout;
   });
diff --git a/utils/pub/git_source.dart b/utils/pub/git_source.dart
index f37db91..fdb0ed4 100644
--- a/utils/pub/git_source.dart
+++ b/utils/pub/git_source.dart
@@ -5,6 +5,9 @@
 library git_source;
 
 import 'dart:async';
+
+import '../../pkg/path/lib/path.dart' as path;
+
 import 'git.dart' as git;
 import 'io.dart';
 import 'package.dart';
@@ -42,7 +45,7 @@
             "Please ensure Git is correctly installed.");
       }
 
-      ensureDir(join(systemCacheRoot, 'cache'));
+      ensureDir(path.join(systemCacheRoot, 'cache'));
       return _ensureRepoCache(id);
     }).then((_) => systemCacheDirectory(id)).then((path) {
       revisionCachePath = path;
@@ -61,7 +64,7 @@
   Future<String> systemCacheDirectory(PackageId id) {
     return _revisionAt(id).then((rev) {
       var revisionCacheName = '${id.name}-$rev';
-      return join(systemCacheRoot, revisionCacheName);
+      return path.join(systemCacheRoot, revisionCacheName);
     });
   }
   /// Ensures [description] is a Git URL.
@@ -79,7 +82,7 @@
 
     if (!description.isEmpty) {
       var plural = description.length > 1;
-      var keys = Strings.join(description.keys, ', ');
+      var keys = description.keys.join(', ');
       throw new FormatException("Invalid key${plural ? 's' : ''}: $keys.");
     }
   }
@@ -148,7 +151,7 @@
   /// [id] (the one in `<system cache>/git/cache`).
   String _repoCachePath(PackageId id) {
     var repoCacheName = '${id.name}-${sha1(_getUrl(id))}';
-    return join(systemCacheRoot, 'cache', repoCacheName);
+    return path.join(systemCacheRoot, 'cache', repoCacheName);
   }
 
   /// Returns the repository URL for [id].
diff --git a/utils/pub/hosted_source.dart b/utils/pub/hosted_source.dart
index ef56462..dda00a4 100644
--- a/utils/pub/hosted_source.dart
+++ b/utils/pub/hosted_source.dart
@@ -11,6 +11,8 @@
 
 // TODO(nweiz): Make this import better.
 import '../../pkg/http/lib/http.dart' as http;
+import '../../pkg/path/lib/path.dart' as path;
+
 import 'http.dart';
 import 'io.dart';
 import 'log.dart' as log;
@@ -99,7 +101,7 @@
     });
 
     return new Future.immediate(
-        join(systemCacheRoot, urlDir, "${parsed.first}-${id.version}"));
+        path.join(systemCacheRoot, urlDir, "${parsed.first}-${id.version}"));
   }
 
   String packageName(description) => _parseDescription(description).first;
diff --git a/utils/pub/io.dart b/utils/pub/io.dart
index c439384..82614ca 100644
--- a/utils/pub/io.dart
+++ b/utils/pub/io.dart
@@ -22,17 +22,6 @@
 
 final NEWLINE_PATTERN = new RegExp("\r\n?|\n\r?");
 
-/// Joins a number of path string parts into a single path. Handles
-/// platform-specific path separators. Parts can be [String], [Directory], or
-/// [File] objects.
-String join(part1, [part2, part3, part4, part5, part6, part7, part8]) {
-  var parts = [part1, part2, part3, part4, part5, part6, part7, part8]
-      .map((part) => part == null ? null : _getPath(part)).toList();
-
-  return path.join(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5],
-      parts[6], parts[7]);
-}
-
 /// Returns whether or not [entry] is nested somewhere within [dir]. This just
 /// performs a path comparison; it doesn't look at the actual filesystem.
 bool isBeneath(String entry, String dir) {
@@ -40,92 +29,82 @@
   return !path.isAbsolute(relative) && path.split(relative)[0] != '..';
 }
 
-/// Determines if [path], which can be a [String] file path, a [File], or a
-/// [Directory] exists on the file system.
-bool entryExists(path) => fileExists(path) || dirExists(path);
+/// Determines if a file or directory at [path] exists.
+bool entryExists(String path) => fileExists(path) || dirExists(path);
 
-/// Determines if [file], which can be a [String] file path or a [File], exists
-/// on the file system.
-bool fileExists(file) => _getFile(file).existsSync();
+/// Determines if [file] exists on the file system.
+bool fileExists(String file) => new File(file).existsSync();
 
-/// Reads the contents of the text file [file], which can either be a [String]
-/// or a [File].
-String readTextFile(file) => _getFile(file).readAsStringSync(Encoding.UTF_8);
+/// Reads the contents of the text file [file].
+String readTextFile(String file) =>
+    new File(file).readAsStringSync(Encoding.UTF_8);
 
-/// Reads the contents of the binary file [file], which can either be a [String]
-/// or a [File].
-List<int> readBinaryFile(file) {
-  var path = _getPath(file);
-  log.io("Reading binary file $path.");
-  var contents = new File(path).readAsBytesSync();
-  log.io("Read ${contents.length} bytes from $path.");
+/// Reads the contents of the binary file [file].
+List<int> readBinaryFile(String file) {
+  log.io("Reading binary file $file.");
+  var contents = new File(file).readAsBytesSync();
+  log.io("Read ${contents.length} bytes from $file.");
   return contents;
 }
 
-/// Creates [file] (which can either be a [String] or a [File]), and writes
-/// [contents] to it.
+/// Creates [file] and writes [contents] to it.
 ///
 /// If [dontLogContents] is true, the contents of the file will never be logged.
-File writeTextFile(file, String contents, {dontLogContents: false}) {
-  var path = _getPath(file);
-  file = new File(path);
-
+String writeTextFile(String file, String contents, {dontLogContents: false}) {
   // Sanity check: don't spew a huge file.
-  log.io("Writing ${contents.length} characters to text file $path.");
+  log.io("Writing ${contents.length} characters to text file $file.");
   if (!dontLogContents && contents.length < 1024 * 1024) {
     log.fine("Contents:\n$contents");
   }
 
-  return file..writeAsStringSync(contents);
-}
-
-/// Deletes [file], which can be a [String] or a [File].
-File deleteFile(file) => _getFile(file)..delete();
-
-/// Creates [file] (which can either be a [String] or a [File]), and writes
-/// [contents] to it.
-File writeBinaryFile(file, List<int> contents) {
-  var path = _getPath(file);
-  file = new File(path);
-
-  log.io("Writing ${contents.length} bytes to binary file $path.");
-  file.openSync(FileMode.WRITE)
-      ..writeListSync(contents, 0, contents.length)
-      ..closeSync();
-  log.fine("Wrote text file $path.");
+  new File(file).writeAsStringSync(contents);
   return file;
 }
 
-/// Writes [stream] to a new file at [path], which may be a [String] or a
-/// [File]. Will replace any file already at that path. Completes when the file
-/// is done being written.
-Future<File> createFileFromStream(Stream<List<int>> stream, path) {
-  path = _getPath(path);
+/// Deletes [file].
+void deleteFile(String file) {
+  new File(file).delete();
+}
 
-  log.io("Creating $path from stream.");
+/// Creates [file] and writes [contents] to it.
+String writeBinaryFile(String file, List<int> contents) {
+  log.io("Writing ${contents.length} bytes to binary file $file.");
+  new File(file).openSync(FileMode.WRITE)
+      ..writeListSync(contents, 0, contents.length)
+      ..closeSync();
+  log.fine("Wrote text file $file.");
+  return file;
+}
 
-  var file = new File(path);
-  return stream.pipe(wrapOutputStream(file.openOutputStream())).then((_) {
-    log.fine("Created $path from stream.");
+/// Writes [stream] to a new file at path [file]. Will replace any file already
+/// at that path. Completes when the file is done being written.
+Future<String> createFileFromStream(Stream<List<int>> stream, String file) {
+  log.io("Creating $file from stream.");
+
+  var outputStream = new File(file).openOutputStream();
+  return stream.pipe(wrapOutputStream(outputStream)).then((_) {
+    log.fine("Created $file from stream.");
+    return file;
   });
 }
 
 /// Creates a directory [dir].
-Directory createDir(dir) => _getDirectory(dir)..createSync();
+String createDir(String dir) {
+  new Directory(dir).createSync();
+  return dir;
+}
 
 /// Ensures that [dirPath] and all its parent directories exist. If they don't
 /// exist, creates them.
-Directory ensureDir(dirPath) {
-  dirPath = _getPath(dirPath);
-
+String ensureDir(String dirPath) {
   log.fine("Ensuring directory $dirPath exists.");
   var dir = new Directory(dirPath);
-  if (dirPath == '.' || dirExists(dirPath)) return dir;
+  if (dirPath == '.' || dirExists(dirPath)) return dirPath;
 
   ensureDir(path.dirname(dirPath));
 
   try {
-    createDir(dir);
+    createDir(dirPath);
   } on DirectoryIOException catch (ex) {
     // Error 17 means the directory already exists (or 183 on Windows).
     if (ex.osError.errorCode == 17 || ex.osError.errorCode == 183) {
@@ -135,7 +114,7 @@
     }
   }
 
-  return dir;
+  return dirPath;
 }
 
 /// Creates a temp directory whose name will be based on [dir] with a unique
@@ -143,35 +122,32 @@
 /// created in a platform-dependent temporary location. Returns the path of the
 /// created directory.
 String createTempDir([dir = '']) {
-  var tempDir = _getDirectory(dir).createTempSync();
+  var tempDir = new Directory(dir).createTempSync();
   log.io("Created temp directory ${tempDir.path}");
   return tempDir.path;
 }
 
-/// Asynchronously recursively deletes [dir], which can be a [String] or a
-/// [Directory]. Returns a [Future] that completes when the deletion is done.
-Future<Directory> deleteDir(dir) {
-  dir = _getDirectory(dir);
-
-  return _attemptRetryable(() => log.ioAsync("delete directory ${dir.path}",
-      dir.delete(recursive: true)));
+/// Asynchronously recursively deletes [dir]. Returns a [Future] that completes
+/// when the deletion is done.
+Future<String> deleteDir(String dir) {
+  return _attemptRetryable(() => log.ioAsync("delete directory $dir",
+      new Directory(dir).delete(recursive: true).then((_) => dir)));
 }
 
-/// Asynchronously lists the contents of [dir], which can be a [String]
-/// directory path or a [Directory]. If [recursive] is `true`, lists
+/// Asynchronously lists the contents of [dir]. If [recursive] is `true`, lists
 /// subdirectory contents (defaults to `false`). If [includeHiddenFiles] is
 /// `true`, includes files and directories beginning with `.` (defaults to
 /// `false`).
 ///
 /// If [dir] is a string, the returned paths are guaranteed to begin with it.
-Future<List<String>> listDir(dir,
+Future<List<String>> listDir(String dir,
     {bool recursive: false, bool includeHiddenFiles: false}) {
-  Future<List<String>> doList(Directory dir, Set<String> listedDirectories) {
+  Future<List<String>> doList(String dir, Set<String> listedDirectories) {
     var contents = <String>[];
     var completer = new Completer<List<String>>();
 
     // Avoid recursive symlinks.
-    var resolvedPath = new File(dir.path).fullPathSync();
+    var resolvedPath = new File(dir).fullPathSync();
     if (listedDirectories.contains(resolvedPath)) {
       return new Future.immediate([]);
     }
@@ -179,15 +155,14 @@
     listedDirectories = new Set<String>.from(listedDirectories);
     listedDirectories.add(resolvedPath);
 
-    log.io("Listing directory ${dir.path}.");
-    var lister = dir.list();
+    log.io("Listing directory $dir.");
+    var lister = new Directory(dir).list();
 
     lister.onDone = (done) {
       // TODO(rnystrom): May need to sort here if it turns out onDir and onFile
       // aren't guaranteed to be called in a certain order. So far, they seem to.
       if (done) {
-        log.fine("Listed directory ${dir.path}:\n"
-                  "${Strings.join(contents, '\n')}");
+        log.fine("Listed directory $dir:\n${contents.join('\n')}");
         completer.complete(contents);
       }
     };
@@ -204,19 +179,19 @@
     lister.onError = (error) => completer.completeError(error, stackTrace);
     lister.onDir = (file) {
       if (!includeHiddenFiles && path.basename(file).startsWith('.')) return;
-      file = join(dir, path.basename(file));
+      file = path.join(dir, path.basename(file));
       contents.add(file);
       // TODO(nweiz): don't manually recurse once issue 7358 is fixed. Note that
       // once we remove the manual recursion, we'll need to explicitly filter
       // out files in hidden directories.
       if (recursive) {
-        children.add(doList(new Directory(file), listedDirectories));
+        children.add(doList(file, listedDirectories));
       }
     };
 
     lister.onFile = (file) {
       if (!includeHiddenFiles && path.basename(file).startsWith('.')) return;
-      contents.add(join(dir, path.basename(file)));
+      contents.add(path.join(dir, path.basename(file)));
     };
 
     return completer.future.then((contents) {
@@ -227,17 +202,16 @@
     });
   }
 
-  return doList(_getDirectory(dir), new Set<String>());
+  return doList(dir, new Set<String>());
 }
 
-/// Determines if [dir], which can be a [String] directory path or a
-/// [Directory], exists on the file system.
-bool dirExists(dir) => _getDirectory(dir).existsSync();
+/// Determines if [dir] exists on the file system.
+bool dirExists(String dir) => new Directory(dir).existsSync();
 
 /// "Cleans" [dir]. If that directory already exists, it will be deleted. Then a
 /// new empty directory will be created. Returns a [Future] that completes when
 /// the new clean directory is created.
-Future<Directory> cleanDir(dir) {
+Future<String> cleanDir(String dir) {
   return defer(() {
     if (dirExists(dir)) {
       // Delete it first.
@@ -251,13 +225,12 @@
 
 /// Renames (i.e. moves) the directory [from] to [to]. Returns a [Future] with
 /// the destination directory.
-Future<Directory> renameDir(from, String to) {
-  from = _getDirectory(from);
-  log.io("Renaming directory ${from.path} to $to.");
+Future<String> renameDir(String from, String to) {
+  log.io("Renaming directory $from to $to.");
 
-  return _attemptRetryable(() => from.rename(to)).then((dir) {
-    log.fine("Renamed directory ${from.path} to $to.");
-    return dir;
+  return _attemptRetryable(() => new Directory(from).rename(to)).then((dir) {
+    log.fine("Renamed directory $from to $to.");
+    return to;
   });
 }
 
@@ -291,15 +264,11 @@
   return makeAttempt(null);
 }
 
-/// Creates a new symlink that creates an alias from [from] to [to], both of
-/// which can be a [String], [File], or [Directory]. Returns a [Future] which
-/// completes to the symlink file (i.e. [to]).
+/// Creates a new symlink that creates an alias from [from] to [to]. Returns a
+/// [Future] which completes to the symlink file (i.e. [to]).
 ///
 /// Note that on Windows, only directories may be symlinked to.
-Future<File> createSymlink(from, to) {
-  from = _getPath(from);
-  to = _getPath(to);
-
+Future<String> createSymlink(String from, String to) {
   log.fine("Creating symlink ($to is a symlink to $from)");
 
   var command = 'ln';
@@ -315,22 +284,19 @@
     args = ['/j', to, from];
   }
 
-  return runProcess(command, args).then((result) {
-    // TODO(rnystrom): Check exit code and output?
-    return new File(to);
-  });
+  // TODO(rnystrom): Check exit code and output?
+  return runProcess(command, args).then((result) => to);
 }
 
 /// Creates a new symlink that creates an alias from the `lib` directory of
-/// package [from] to [to], both of which can be a [String], [File], or
-/// [Directory]. Returns a [Future] which completes to the symlink file (i.e.
-/// [to]). If [from] does not have a `lib` directory, this shows a warning if
-/// appropriate and then does nothing.
-Future<File> createPackageSymlink(String name, from, to,
+/// package [from] to [to]. Returns a [Future] which completes to the symlink
+/// file (i.e. [to]). If [from] does not have a `lib` directory, this shows a
+/// warning if appropriate and then does nothing.
+Future<String> createPackageSymlink(String name, String from, String to,
     {bool isSelfLink: false}) {
   return defer(() {
     // See if the package has a "lib" directory.
-    from = join(from, 'lib');
+    from = path.join(from, 'lib');
     log.fine("Creating ${isSelfLink ? "self" : ""}link for package '$name'.");
     if (dirExists(from)) return createSymlink(from, to);
 
@@ -342,7 +308,7 @@
                   'you will not be able to import any libraries from it.');
     }
 
-    return _getFile(to);
+    return to;
   });
 }
 
@@ -360,7 +326,7 @@
     utilDir = path.dirname(utilDir);
   }
 
-  return path.normalize(join(utilDir, 'pub', target));
+  return path.normalize(path.join(utilDir, 'pub', target));
 }
 
 // TODO(nweiz): add a ByteSink wrapper to make writing strings to stdout/stderr
@@ -643,8 +609,8 @@
 /// Calls [fn] with appropriately modified arguments. [fn] should have the same
 /// signature as [Process.start], except that the returned [Future] may have a
 /// type other than [Process].
-Future _doProcess(Function fn, String executable, List<String> args, workingDir,
-    Map<String, String> environment) {
+Future _doProcess(Function fn, String executable, List<String> args,
+    String workingDir, Map<String, String> environment) {
   // TODO(rnystrom): Should dart:io just handle this?
   // Spawning a process on Windows will not look for the executable in the
   // system path. So, if executable looks like it needs that (i.e. it doesn't
@@ -657,7 +623,7 @@
 
   final options = new ProcessOptions();
   if (workingDir != null) {
-    options.workingDirectory = _getDirectory(workingDir).path;
+    options.workingDirectory = workingDir;
   }
 
   if (environment != null) {
@@ -681,7 +647,7 @@
 Future timeout(Future input, int milliseconds, String description) {
   bool completed = false;
   var completer = new Completer();
-  var timer = new Timer(new Duration(milliseconds: milliseconds), () {
+  var timer = new Timer(new Duration(milliseconds: milliseconds), (_) {
     completed = true;
     completer.completeError(new TimeoutException(
         'Timed out while $description.'));
@@ -713,11 +679,9 @@
   });
 }
 
-/// Extracts a `.tar.gz` file from [stream] to [destination], which can be a
-/// directory or a path. Returns whether or not the extraction was successful.
-Future<bool> extractTarGz(Stream<List<int>> stream, destination) {
-  destination = _getPath(destination);
-
+/// Extracts a `.tar.gz` file from [stream] to [destination]. Returns whether
+/// or not the extraction was successful.
+Future<bool> extractTarGz(Stream<List<int>> stream, String destination) {
   log.fine("Extracting .tar.gz stream to $destination.");
 
   if (Platform.operatingSystem == "windows") {
@@ -761,7 +725,8 @@
 
   return withTempDir((tempDir) {
     // Write the archive to a temp file.
-    return createFileFromStream(stream, join(tempDir, 'data.tar.gz')).then((_) {
+    var dataFile = path.join(tempDir, 'data.tar.gz');
+    return createFileFromStream(stream, dataFile).then((_) {
       // 7zip can't unarchive from gzip -> tar -> destination all in one step
       // first we un-gzip it to a tar file.
       // Note: Setting the working directory instead of passing in a full file
@@ -770,8 +735,8 @@
     }).then((result) {
       if (result.exitCode != 0) {
         throw 'Could not un-gzip (exit code ${result.exitCode}). Error:\n'
-            '${Strings.join(result.stdout, "\n")}\n'
-            '${Strings.join(result.stderr, "\n")}';
+            '${result.stdout.join("\n")}\n'
+            '${result.stderr.join("\n")}';
       }
       // Find the tar file we just created since we don't know its name.
       return listDir(tempDir);
@@ -791,8 +756,8 @@
     }).then((result) {
       if (result.exitCode != 0) {
         throw 'Could not un-tar (exit code ${result.exitCode}). Error:\n'
-            '${Strings.join(result.stdout, "\n")}\n'
-            '${Strings.join(result.stderr, "\n")}';
+            '${result.stdout.join("\n")}\n'
+            '${result.stderr.join("\n")}';
       }
       return true;
     });
@@ -816,7 +781,7 @@
   if (baseDir == null) baseDir = path.current;
   baseDir = path.absolute(baseDir);
   contents = contents.map((entry) {
-    entry = path.absolute(_getPath(entry));
+    entry = path.absolute(entry);
     if (!isBeneath(entry, baseDir)) {
       throw 'Entry $entry is not inside $baseDir.';
     }
@@ -825,7 +790,7 @@
 
   if (Platform.operatingSystem != "windows") {
     var args = ["--create", "--gzip", "--directory", baseDir];
-    args.addAll(contents.map(_getPath));
+    args.addAll(contents);
     // TODO(nweiz): It's possible that enough command-line arguments will make
     // the process choke, so at some point we should save the arguments to a
     // file and pass them in via --files-from for tar and -i@filename for 7zip.
@@ -842,7 +807,7 @@
 
   withTempDir((tempDir) {
     // Create the tar file.
-    var tarFile = join(tempDir, "intermediate.tar");
+    var tarFile = path.join(tempDir, "intermediate.tar");
     var args = ["a", "-w$baseDir", tarFile];
     args.addAll(contents.map((entry) => '-i!"$entry"'));
 
@@ -897,31 +862,6 @@
   bool get success => exitCode == 0;
 }
 
-/// Gets a dart:io [File] for [entry], which can either already be a File or be
-/// a path string.
-File _getFile(entry) {
-  if (entry is File) return entry;
-  if (entry is String) return new File(entry);
-  throw 'Entry $entry is not a supported type.';
-}
-
-/// Gets the path string for [entry], which can either already be a path string,
-/// or be a [File] or [Directory]. Allows working generically with "file-like"
-/// objects.
-String _getPath(entry) {
-  if (entry is String) return entry;
-  if (entry is File) return entry.name;
-  if (entry is Directory) return entry.path;
-  throw 'Entry $entry is not a supported type.';
-}
-
-/// Gets a [Directory] for [entry], which can either already be one, or be a
-/// [String].
-Directory _getDirectory(entry) {
-  if (entry is Directory) return entry;
-  return new Directory(entry);
-}
-
 /// Gets a [Uri] for [uri], which can either already be one, or be a [String].
 Uri _getUri(uri) {
   if (uri is Uri) return uri;
diff --git a/utils/pub/log.dart b/utils/pub/log.dart
index 06a4748..9a555ea 100644
--- a/utils/pub/log.dart
+++ b/utils/pub/log.dart
@@ -110,7 +110,7 @@
 /// Logs the spawning of an [executable] process with [arguments] at [IO]
 /// level.
 void process(String executable, List<String> arguments) {
-  io("Spawning $executable ${Strings.join(arguments, ' ')}");
+  io("Spawning $executable ${arguments.join(' ')}");
 }
 
 /// Logs the results of running [executable].
diff --git a/utils/pub/oauth2.dart b/utils/pub/oauth2.dart
index 3ea33cc..276fb25 100644
--- a/utils/pub/oauth2.dart
+++ b/utils/pub/oauth2.dart
@@ -118,7 +118,7 @@
     if (_credentials != null) return _credentials;
 
     var path = _credentialsFile(cache);
-    if (!fileExists(path)) return;
+    if (!fileExists(path)) return null;
 
     var credentials = new Credentials.fromJson(readTextFile(path));
     if (credentials.isExpired && !credentials.canRefresh) {
@@ -147,7 +147,7 @@
 
 /// The path to the file in which the user's OAuth2 credentials are stored.
 String _credentialsFile(SystemCache cache) =>
-  join(cache.rootDir, 'credentials.json');
+    path.join(cache.rootDir, 'credentials.json');
 
 /// Gets the user to authorize pub as a client of pub.dartlang.org via oauth2.
 /// Returns a Future that will complete to a fully-authorized [Client].
diff --git a/utils/pub/pub.dart b/utils/pub/pub.dart
index a837163..569c63c 100644
--- a/utils/pub/pub.dart
+++ b/utils/pub/pub.dart
@@ -6,12 +6,12 @@
 library pub;
 
 import 'dart:async';
-import '../../pkg/args/lib/args.dart';
-import '../../pkg/path/lib/path.dart' as path;
 import 'dart:io';
 import 'dart:math';
-import 'http.dart';
-import 'io.dart';
+
+import '../../pkg/args/lib/args.dart';
+import '../../pkg/path/lib/path.dart' as path;
+
 import 'command_help.dart';
 import 'command_install.dart';
 import 'command_lish.dart';
@@ -20,6 +20,8 @@
 import 'command_version.dart';
 import 'entrypoint.dart';
 import 'exit_codes.dart' as exit_codes;
+import 'http.dart';
+import 'io.dart';
 import 'log.dart' as log;
 import 'package.dart';
 import 'pubspec.dart';
@@ -116,7 +118,7 @@
     cacheDir = Platform.environment['PUB_CACHE'];
   } else if (Platform.operatingSystem == 'windows') {
     var appData = Platform.environment['APPDATA'];
-    cacheDir = join(appData, 'Pub', 'Cache');
+    cacheDir = path.join(appData, 'Pub', 'Cache');
   } else {
     cacheDir = '${Platform.environment['HOME']}/.pub-cache';
   }
diff --git a/utils/pub/sdk.dart b/utils/pub/sdk.dart
index 98007b5..1db2a04 100644
--- a/utils/pub/sdk.dart
+++ b/utils/pub/sdk.dart
@@ -8,6 +8,8 @@
 import 'dart:io';
 
 import '../../pkg/path/lib/path.dart' as path;
+
+import 'io.dart';
 import 'log.dart' as log;
 import 'version.dart';
 
@@ -38,7 +40,7 @@
 /// Determine the SDK's version number.
 Version _getVersion() {
   var revisionPath = path.join(rootDirectory, "version");
-  var version = new File(revisionPath).readAsStringSync().trim();
+  var version = readTextFile(revisionPath).trim();
 
   // Given a version file like: 0.1.2.0_r17495
   // We create a semver like:   0.1.2+0.r17495
diff --git a/utils/pub/sdk_source.dart b/utils/pub/sdk_source.dart
index 6fbba09..1544152 100644
--- a/utils/pub/sdk_source.dart
+++ b/utils/pub/sdk_source.dart
@@ -5,6 +5,9 @@
 library sdk_source;
 
 import 'dart:async';
+
+import '../../pkg/path/lib/path.dart' as path;
+
 import 'io.dart';
 import 'package.dart';
 import 'pubspec.dart';
@@ -45,7 +48,7 @@
   /// Gets the path in the SDK's "pkg" directory to the directory containing
   /// package [id]. Returns `null` if the package could not be found.
   String _getPackagePath(PackageId id) {
-    var pkgPath = join(sdk.rootDirectory, "pkg", id.description);
+    var pkgPath = path.join(sdk.rootDirectory, "pkg", id.description);
     return dirExists(pkgPath) ? pkgPath : null;
   }
 }
diff --git a/utils/pub/source.dart b/utils/pub/source.dart
index 30fd5eb..1fd9327 100644
--- a/utils/pub/source.dart
+++ b/utils/pub/source.dart
@@ -47,7 +47,7 @@
   /// The root directory of this source's cache within the system cache.
   ///
   /// This shouldn't be overridden by subclasses.
-  String get systemCacheRoot => join(systemCache.rootDir, name);
+  String get systemCacheRoot => path.join(systemCache.rootDir, name);
 
   /// Records the system cache to which this source belongs.
   ///
@@ -144,9 +144,9 @@
   ///   * It has no pubspec.
   Future<bool> _isCachedPackageCorrupted(String packageDir) {
     return defer(() {
-      if (!fileExists(join(packageDir, "pubspec.yaml"))) return true;
+      if (!fileExists(path.join(packageDir, "pubspec.yaml"))) return true;
 
-      var libDir = join(packageDir, "lib");
+      var libDir = path.join(packageDir, "lib");
       if (dirExists(libDir)) {
         return listDir(libDir).then((contents) => contents.length == 0);
       }
diff --git a/utils/pub/system_cache.dart b/utils/pub/system_cache.dart
index 377ac17..8bd3178 100644
--- a/utils/pub/system_cache.dart
+++ b/utils/pub/system_cache.dart
@@ -7,6 +7,8 @@
 import 'dart:io';
 import 'dart:async';
 
+import '../../pkg/path/lib/path.dart' as path;
+
 import 'git_source.dart';
 import 'hosted_source.dart';
 import 'io.dart';
@@ -30,7 +32,7 @@
   /// The root directory where this package cache is located.
   final String rootDir;
 
-  String get tempDir => join(rootDir, '_temp');
+  String get tempDir => path.join(rootDir, '_temp');
 
   /// Packages which are currently being asynchronously installed to the cache.
   final Map<PackageId, Future<Package>> _pendingInstalls;
@@ -105,7 +107,7 @@
   /// cache so that it can move the directory from it.
   String createTempDir() {
     var temp = ensureDir(tempDir);
-    return io.createTempDir(join(temp, 'dir'));
+    return io.createTempDir(path.join(temp, 'dir'));
   }
 
   /// Delete's the system cache's internal temp directory.
diff --git a/utils/pub/utils.dart b/utils/pub/utils.dart
index 6012907..a058e48 100644
--- a/utils/pub/utils.dart
+++ b/utils/pub/utils.dart
@@ -158,7 +158,8 @@
 /// Returns a [Future] that completes in [milliseconds].
 Future sleep(int milliseconds) {
   var completer = new Completer();
-  new Timer(new Duration(milliseconds: milliseconds), completer.complete);
+  new Timer(new Duration(milliseconds: milliseconds),
+      (_) => completer.complete());
   return completer.future;
 }
 
@@ -326,10 +327,10 @@
     value = (value == null || value.isEmpty) ? null : encodeUriComponent(value);
     pairs.add([key, value]);
   });
-  return Strings.join(pairs.map((pair) {
+  return pairs.map((pair) {
     if (pair[1] == null) return pair[0];
     return "${pair[0]}=${pair[1]}";
-  }), "&");
+  }).join("&");
 }
 
 /// Add all key/value pairs from [source] to [destination], overwriting any
diff --git a/utils/pub/validator.dart b/utils/pub/validator.dart
index 72f65d1..4bfff03 100644
--- a/utils/pub/validator.dart
+++ b/utils/pub/validator.dart
@@ -75,7 +75,7 @@
       if (!errors.isEmpty) {
         log.error("Missing requirements:");
         for (var error in errors) {
-          log.error("* ${Strings.join(error.split('\n'), '\n  ')}");
+          log.error("* ${error.split('\n').join('\n  ')}");
         }
         log.error("");
       }
@@ -83,7 +83,7 @@
       if (!warnings.isEmpty) {
         log.warning("Suggestions:");
         for (var warning in warnings) {
-          log.warning("* ${Strings.join(warning.split('\n'), '\n  ')}");
+          log.warning("* ${warning.split('\n').join('\n  ')}");
         }
         log.warning("");
       }
diff --git a/utils/pub/validator/compiled_dartdoc.dart b/utils/pub/validator/compiled_dartdoc.dart
index 20f69be..2d340ba 100644
--- a/utils/pub/validator/compiled_dartdoc.dart
+++ b/utils/pub/validator/compiled_dartdoc.dart
@@ -28,10 +28,10 @@
         // Look for tell-tale Dartdoc output files all in the same directory.
         var files = [
           entry,
-          join(dir, "index.html"),
-          join(dir, "styles.css"),
-          join(dir, "dart-logo-small.png"),
-          join(dir, "client-live-nav.js")
+          path.join(dir, "index.html"),
+          path.join(dir, "styles.css"),
+          path.join(dir, "dart-logo-small.png"),
+          path.join(dir, "client-live-nav.js")
         ];
 
         if (files.every((val) => fileExists(val))) {
diff --git a/utils/pub/validator/lib.dart b/utils/pub/validator/lib.dart
index c72d309..5a637a4 100644
--- a/utils/pub/validator/lib.dart
+++ b/utils/pub/validator/lib.dart
@@ -23,7 +23,7 @@
     : super(entrypoint);
 
   Future validate() {
-    var libDir = join(entrypoint.root.dir, "lib");
+    var libDir = path.join(entrypoint.root.dir, "lib");
 
     return defer(() {
       if (!dirExists(libDir)) {
diff --git a/utils/pub/validator/name.dart b/utils/pub/validator/name.dart
index 6a8cd91..2ad4bc9 100644
--- a/utils/pub/validator/name.dart
+++ b/utils/pub/validator/name.dart
@@ -48,7 +48,7 @@
   /// Returns a list of all libraries in the current package as paths relative
   /// to the package's root directory.
   Future<List<String>> get _libraries {
-    var libDir = join(entrypoint.root.dir, "lib");
+    var libDir = path.join(entrypoint.root.dir, "lib");
     return defer(() {
       if (!dirExists(libDir)) return [];
       return listDir(libDir, recursive: true);
diff --git a/utils/tests/pub/command_line_config.dart b/utils/tests/pub/command_line_config.dart
index d15126b..b7b7b34 100644
--- a/utils/tests/pub/command_line_config.dart
+++ b/utils/tests/pub/command_line_config.dart
@@ -116,7 +116,7 @@
   String _indent(String str) {
     // TODO(nweiz): Use this simpler code once issue 2980 is fixed.
     // return str.replaceAll(new RegExp("^", multiLine: true), "  ");
-    return Strings.join(str.split("\n").map((line) => "  $line"), "\n");
+    return str.split("\n").map((line) => "  $line").join("\n");
   }
 }
 
diff --git a/utils/tests/pub/io_test.dart b/utils/tests/pub/io_test.dart
index 6c6922c..990dd6c 100644
--- a/utils/tests/pub/io_test.dart
+++ b/utils/tests/pub/io_test.dart
@@ -4,7 +4,9 @@
 
 library io_test;
 
+import '../../../pkg/path/lib/path.dart' as path;
 import '../../../pkg/unittest/lib/unittest.dart';
+
 import '../../pub/io.dart';
 import '../../pub/utils.dart';
 import 'test_pub.dart';
@@ -14,119 +16,119 @@
 
   group('listDir', () {
     test('lists a simple directory non-recursively', () {
-      expect(withTempDir((path) {
+      expect(withTempDir((temp) {
         var future = defer(() {
-          writeTextFile(join(path, 'file1.txt'), '');
-          writeTextFile(join(path, 'file2.txt'), '');
-          createDir(join(path, 'subdir'));
-          writeTextFile(join(path, 'subdir', 'file3.txt'), '');
-          return listDir(path);
+          writeTextFile(path.join(temp, 'file1.txt'), '');
+          writeTextFile(path.join(temp, 'file2.txt'), '');
+          createDir(path.join(temp, 'subdir'));
+          writeTextFile(path.join(temp, 'subdir', 'file3.txt'), '');
+          return listDir(temp);
         });
         expect(future, completion(unorderedEquals([
-          join(path, 'file1.txt'),
-          join(path, 'file2.txt'),
-          join(path, 'subdir')
+          path.join(temp, 'file1.txt'),
+          path.join(temp, 'file2.txt'),
+          path.join(temp, 'subdir')
         ])));
         return future;
       }), completes);
     });
 
     test('lists a simple directory recursively', () {
-      expect(withTempDir((path) {
+      expect(withTempDir((temp) {
         var future = defer(() {
-          writeTextFile(join(path, 'file1.txt'), '');
-          writeTextFile(join(path, 'file2.txt'), '');
-          createDir(join(path, 'subdir'));
-          writeTextFile(join(path, 'subdir', 'file3.txt'), '');
-          return listDir(path, recursive: true);
+          writeTextFile(path.join(temp, 'file1.txt'), '');
+          writeTextFile(path.join(temp, 'file2.txt'), '');
+          createDir(path.join(temp, 'subdir'));
+          writeTextFile(path.join(temp, 'subdir', 'file3.txt'), '');
+          return listDir(temp, recursive: true);
         });
 
         expect(future, completion(unorderedEquals([
-          join(path, 'file1.txt'),
-          join(path, 'file2.txt'),
-          join(path, 'subdir'),
-          join(path, 'subdir', 'file3.txt'),
+          path.join(temp, 'file1.txt'),
+          path.join(temp, 'file2.txt'),
+          path.join(temp, 'subdir'),
+          path.join(temp, 'subdir', 'file3.txt'),
         ])));
         return future;
       }), completes);
     });
 
     test('ignores hidden files by default', () {
-      expect(withTempDir((path) {
+      expect(withTempDir((temp) {
         var future = defer(() {
-          writeTextFile(join(path, 'file1.txt'), '');
-          writeTextFile(join(path, 'file2.txt'), '');
-          writeTextFile(join(path, '.file3.txt'), '');
-          createDir(join(path, '.subdir'));
-          writeTextFile(join(path, '.subdir', 'file3.txt'), '');
-          return listDir(path, recursive: true);
+          writeTextFile(path.join(temp, 'file1.txt'), '');
+          writeTextFile(path.join(temp, 'file2.txt'), '');
+          writeTextFile(path.join(temp, '.file3.txt'), '');
+          createDir(path.join(temp, '.subdir'));
+          writeTextFile(path.join(temp, '.subdir', 'file3.txt'), '');
+          return listDir(temp, recursive: true);
         });
         expect(future, completion(unorderedEquals([
-          join(path, 'file1.txt'),
-          join(path, 'file2.txt')
+          path.join(temp, 'file1.txt'),
+          path.join(temp, 'file2.txt')
         ])));
         return future;
       }), completes);
     });
 
     test('includes hidden files when told to', () {
-      expect(withTempDir((path) {
+      expect(withTempDir((temp) {
         var future = defer(() {
-          writeTextFile(join(path, 'file1.txt'), '');
-          writeTextFile(join(path, 'file2.txt'), '');
-          writeTextFile(join(path, '.file3.txt'), '');
-          createDir(join(path, '.subdir'));
-          writeTextFile(join(path, '.subdir', 'file3.txt'), '');
-          return listDir(path, recursive: true, includeHiddenFiles: true);
+          writeTextFile(path.join(temp, 'file1.txt'), '');
+          writeTextFile(path.join(temp, 'file2.txt'), '');
+          writeTextFile(path.join(temp, '.file3.txt'), '');
+          createDir(path.join(temp, '.subdir'));
+          writeTextFile(path.join(temp, '.subdir', 'file3.txt'), '');
+          return listDir(temp, recursive: true, includeHiddenFiles: true);
         });
         expect(future, completion(unorderedEquals([
-          join(path, 'file1.txt'),
-          join(path, 'file2.txt'),
-          join(path, '.file3.txt'),
-          join(path, '.subdir'),
-          join(path, '.subdir', 'file3.txt')
+          path.join(temp, 'file1.txt'),
+          path.join(temp, 'file2.txt'),
+          path.join(temp, '.file3.txt'),
+          path.join(temp, '.subdir'),
+          path.join(temp, '.subdir', 'file3.txt')
         ])));
         return future;
       }), completes);
     });
 
     test('returns the unresolved paths for symlinks', () {
-      expect(withTempDir((path) {
-        var dirToList = join(path, 'dir-to-list');
+      expect(withTempDir((temp) {
+        var dirToList = path.join(temp, 'dir-to-list');
         var future = defer(() {
-          createDir(join(path, 'dir1'));
-          writeTextFile(join(path, 'dir1', 'file1.txt'), '');
-          createDir(join(path, 'dir2'));
-          writeTextFile(join(path, 'dir2', 'file2.txt'), '');
+          createDir(path.join(temp, 'dir1'));
+          writeTextFile(path.join(temp, 'dir1', 'file1.txt'), '');
+          createDir(path.join(temp, 'dir2'));
+          writeTextFile(path.join(temp, 'dir2', 'file2.txt'), '');
           createDir(dirToList);
-          return createSymlink(join(path, 'dir1'),
-                               join(dirToList, 'linked-dir1'));
+          return createSymlink(path.join(temp, 'dir1'),
+                               path.join(dirToList, 'linked-dir1'));
         }).then((_) {
-          createDir(join(dirToList, 'subdir'));
+          createDir(path.join(dirToList, 'subdir'));
           return createSymlink(
-                  join(path, 'dir2'),
-                  join(dirToList, 'subdir', 'linked-dir2'));
+                  path.join(temp, 'dir2'),
+                  path.join(dirToList, 'subdir', 'linked-dir2'));
         }).then((_) => listDir(dirToList, recursive: true));
         expect(future, completion(unorderedEquals([
-          join(dirToList, 'linked-dir1'),
-          join(dirToList, 'linked-dir1', 'file1.txt'),
-          join(dirToList, 'subdir'),
-          join(dirToList, 'subdir', 'linked-dir2'),
-          join(dirToList, 'subdir', 'linked-dir2', 'file2.txt'),
+          path.join(dirToList, 'linked-dir1'),
+          path.join(dirToList, 'linked-dir1', 'file1.txt'),
+          path.join(dirToList, 'subdir'),
+          path.join(dirToList, 'subdir', 'linked-dir2'),
+          path.join(dirToList, 'subdir', 'linked-dir2', 'file2.txt'),
         ])));
         return future;
       }), completes);
     });
 
     test('works with recursive symlinks', () {
-      expect(withTempDir((path) {
+      expect(withTempDir((temp) {
         var future = defer(() {
-          writeTextFile(join(path, 'file1.txt'), '');
-          return createSymlink(path, join(path, 'linkdir'));
-        }).then((_) => listDir(path, recursive: true));
+          writeTextFile(path.join(temp, 'file1.txt'), '');
+          return createSymlink(temp, path.join(temp, 'linkdir'));
+        }).then((_) => listDir(temp, recursive: true));
         expect(future, completion(unorderedEquals([
-          join(path, 'file1.txt'),
-          join(path, 'linkdir')
+          path.join(temp, 'file1.txt'),
+          path.join(temp, 'linkdir')
         ])));
         return future;
       }), completes);
diff --git a/utils/tests/pub/test_pub.dart b/utils/tests/pub/test_pub.dart
index cae3a80..2a148f2 100644
--- a/utils/tests/pub/test_pub.dart
+++ b/utils/tests/pub/test_pub.dart
@@ -553,7 +553,7 @@
 /// are assumed to be relative to [sandboxDir].
 void scheduleRename(String from, String to) {
   _schedule((sandboxDir) {
-    return renameDir(join(sandboxDir, from), join(sandboxDir, to));
+    return renameDir(path.join(sandboxDir, from), path.join(sandboxDir, to));
   });
 }
 
@@ -580,7 +580,7 @@
           failures.addAll(result.stderr.map((line) => '| $line'));
         }
 
-        throw new ExpectException(Strings.join(failures, '\n'));
+        throw new ExpectException(failures.join('\n'));
       }
 
       return null;
@@ -632,7 +632,7 @@
 /// [Future] may have a type other than [Process].
 Future _doPub(Function fn, sandboxDir, List args, Future<Uri> tokenEndpoint) {
   String pathInSandbox(String relPath) {
-    return join(path.absolute(sandboxDir), relPath);
+    return path.join(path.absolute(sandboxDir), relPath);
   }
 
   return defer(() {
@@ -743,7 +743,7 @@
 
 void _validateOutputRegex(List<String> failures, String pipe,
                           RegExp expected, List<String> actual) {
-  var actualText = Strings.join(actual, '\n');
+  var actualText = actual.join('\n');
   if (actualText.contains(expected)) return;
 
   if (actual.length == 0) {
@@ -853,15 +853,15 @@
   /// Validates that at least one file in [dir] matching [name] is valid
   /// according to [validate]. [validate] should throw or complete to an
   /// exception if the input path is invalid.
-  Future _validateOneMatch(String dir, Future validate(String path)) {
+  Future _validateOneMatch(String dir, Future validate(String entry)) {
     // Special-case strings to support multi-level names like "myapp/packages".
     if (name is String) {
-      var path = join(dir, name);
+      var entry = path.join(dir, name);
       return defer(() {
-        if (!entryExists(path)) {
-          throw new ExpectException('Entry $path not found.');
+        if (!entryExists(entry)) {
+          throw new ExpectException('Entry $entry not found.');
         }
-        return validate(path);
+        return validate(entry);
       });
     }
 
@@ -929,13 +929,13 @@
 
   /// Creates the file within [dir]. Returns a [Future] that is completed after
   /// the creation is done.
-  Future<File> create(dir) =>
-      defer(() => writeBinaryFile(join(dir, _stringName), contents));
+  Future<String> create(dir) =>
+      defer(() => writeBinaryFile(path.join(dir, _stringName), contents));
 
   /// Deletes the file within [dir]. Returns a [Future] that is completed after
   /// the deletion is done.
   Future delete(dir) =>
-      defer(() => deleteFile(join(dir, _stringName)));
+      defer(() => deleteFile(path.join(dir, _stringName)));
 
   /// Validates that this file correctly matches the actual file at [path].
   Future validate(String path) {
@@ -952,8 +952,7 @@
   /// Loads the contents of the file.
   ByteStream load(List<String> path) {
     if (!path.isEmpty) {
-      var joinedPath = Strings.join(path, '/');
-      throw "Can't load $joinedPath from within $name: not a directory.";
+      throw "Can't load ${path.join('/')} from within $name: not a directory.";
     }
 
     return new ByteStream.fromBytes(contents);
@@ -973,10 +972,10 @@
 
   /// Creates the file within [dir]. Returns a [Future] that is completed after
   /// the creation is done.
-  Future<Directory> create(parentDir) {
+  Future<String> create(parentDir) {
     return defer(() {
       // Create the directory.
-      var dir = ensureDir(join(parentDir, _stringName));
+      var dir = ensureDir(path.join(parentDir, _stringName));
       if (contents == null) return dir;
 
       // Recursively create all of its children.
@@ -989,7 +988,7 @@
   /// Deletes the directory within [dir]. Returns a [Future] that is completed
   /// after the deletion is done.
   Future delete(dir) {
-    return deleteDir(join(dir, _stringName));
+    return deleteDir(path.join(dir, _stringName));
   }
 
   /// Validates that the directory at [path] contains all of the expected
@@ -1019,7 +1018,7 @@
       }
     }
 
-    throw "Directory $name doesn't contain ${Strings.join(path, '/')}.";
+    throw "Directory $name doesn't contain ${path.join('/')}.";
   }
 }
 
@@ -1051,7 +1050,7 @@
   : super(name, contents);
 
   /// Creates the Git repository and commits the contents.
-  Future<Directory> create(parentDir) {
+  Future create(parentDir) {
     return _runGitCommands(parentDir, [
       ['init'],
       ['add', '.'],
@@ -1082,10 +1081,7 @@
 
   /// Schedule a Git command to run in this repository.
   void scheduleGit(List<String> args) {
-    _schedule((parentDir) {
-      var gitDir = new Directory(join(parentDir, name));
-      return _runGit(args, gitDir);
-    });
+    _schedule((parentDir) => _runGit(args, path.join(parentDir, name)));
   }
 
   Future _runGitCommands(parentDir, List<List<String>> commands) {
@@ -1103,7 +1099,7 @@
     });
   }
 
-  Future<String> _runGit(List<String> args, Directory workingDir) {
+  Future<List<String>> _runGit(List<String> args, String workingDir) {
     // Explicitly specify the committer information. Git needs this to commit
     // and we don't want to rely on the buildbots having this already set up.
     var environment = {
@@ -1113,8 +1109,7 @@
       'GIT_COMMITTER_EMAIL': 'pub@dartlang.org'
     };
 
-    return gitlib.run(args, workingDir: workingDir.path,
-        environment: environment);
+    return gitlib.run(args, workingDir: workingDir, environment: environment);
   }
 }
 
@@ -1127,13 +1122,15 @@
 
   /// Creates the files and directories within this tar file, then archives
   /// them, compresses them, and saves the result to [parentDir].
-  Future<File> create(parentDir) {
+  Future<String> create(parentDir) {
     return withTempDir((tempDir) {
       return Future.wait(contents.map((child) => child.create(tempDir)))
           .then((createdContents) {
         return createTarGz(createdContents, baseDir: tempDir).toBytes();
       }).then((bytes) {
-        return new File(join(parentDir, _stringName)).writeAsBytes(bytes);
+        var file = path.join(parentDir, _stringName);
+        writeBinaryFile(file, bytes);
+        return file;
       });
     });
   }
@@ -1151,15 +1148,14 @@
   /// Loads the contents of this tar file.
   ByteStream load(List<String> path) {
     if (!path.isEmpty) {
-      var joinedPath = Strings.join(path, '/');
-      throw "Can't load $joinedPath from within $name: not a directory.";
+      throw "Can't load ${path.join('/')} from within $name: not a directory.";
     }
 
     var controller = new StreamController<List<int>>();
     // TODO(nweiz): propagate any errors to the return value. See issue 3657.
     withTempDir((tempDir) {
       return create(tempDir).then((tar) {
-        var sourceStream = tar.openInputStream();
+        var sourceStream = new File(tar).openInputStream();
         return store(wrapInputStream(sourceStream), controller);
       });
     });
@@ -1176,7 +1172,7 @@
 
   Future validate(String dir) {
     return defer(() {
-      if (entryExists(join(dir, name))) {
+      if (entryExists(path.join(dir, name))) {
         throw new ExpectException('File $name in $dir should not exist.');
       }
     });
@@ -1186,8 +1182,8 @@
     if (path.isEmpty) {
       throw "Can't load the contents of $name: it doesn't exist.";
     } else {
-      throw "Can't load ${Strings.join(path, '/')} from within $name: $name "
-        "doesn't exist.";
+      throw "Can't load ${path.join('/')} from within $name: $name doesn't "
+        "exist.";
     }
   }
 }
@@ -1200,10 +1196,10 @@
 Future<Pair<List<String>, List<String>>> schedulePackageValidation(
     ValidatorCreator fn) {
   return _scheduleValue((sandboxDir) {
-    var cache = new SystemCache.withSources(join(sandboxDir, cachePath));
+    var cache = new SystemCache.withSources(path.join(sandboxDir, cachePath));
 
     return defer(() {
-      var validator = fn(new Entrypoint(join(sandboxDir, appPath), cache));
+      var validator = fn(new Entrypoint(path.join(sandboxDir, appPath), cache));
       return validator.validate().then((_) {
         return new Pair(validator.errors, validator.warnings);
       });
diff --git a/utils/tests/pub/validator_test.dart b/utils/tests/pub/validator_test.dart
index b64f131..3dbb5ad 100644
--- a/utils/tests/pub/validator_test.dart
+++ b/utils/tests/pub/validator_test.dart
@@ -9,11 +9,12 @@
 import 'dart:json' as json;
 import 'dart:math' as math;
 
-import 'test_pub.dart';
 import '../../../pkg/http/lib/http.dart' as http;
 import '../../../pkg/http/lib/testing.dart';
 import '../../../pkg/path/lib/path.dart' as path;
 import '../../../pkg/unittest/lib/unittest.dart';
+
+import 'test_pub.dart';
 import '../../pub/entrypoint.dart';
 import '../../pub/io.dart';
 import '../../pub/validator.dart';
@@ -115,27 +116,27 @@
     });
 
     integration('has a COPYING file', () {
-      file(join(appPath, 'LICENSE'), '').scheduleDelete();
-      file(join(appPath, 'COPYING'), '').scheduleCreate();
+      file(path.join(appPath, 'LICENSE'), '').scheduleDelete();
+      file(path.join(appPath, 'COPYING'), '').scheduleCreate();
       expectNoValidationError(license);
     });
 
     integration('has a prefixed LICENSE file', () {
-      file(join(appPath, 'LICENSE'), '').scheduleDelete();
-      file(join(appPath, 'MIT_LICENSE'), '').scheduleCreate();
+      file(path.join(appPath, 'LICENSE'), '').scheduleDelete();
+      file(path.join(appPath, 'MIT_LICENSE'), '').scheduleCreate();
       expectNoValidationError(license);
     });
 
     integration('has a suffixed LICENSE file', () {
-      file(join(appPath, 'LICENSE'), '').scheduleDelete();
-      file(join(appPath, 'LICENSE.md'), '').scheduleCreate();
+      file(path.join(appPath, 'LICENSE'), '').scheduleDelete();
+      file(path.join(appPath, 'LICENSE.md'), '').scheduleCreate();
       expectNoValidationError(license);
     });
 
     integration('has "authors" instead of "author"', () {
-      var package = package("test_pkg", "1.0.0");
-      package["authors"] = [package.remove("author")];
-      dir(appPath, [pubspec(package)]).scheduleCreate();
+      var pkg = package("test_pkg", "1.0.0");
+      pkg["authors"] = [pkg.remove("author")];
+      dir(appPath, [pubspec(pkg)]).scheduleCreate();
       expectNoValidationError(pubspecField);
     });
 
@@ -206,73 +207,73 @@
     setUp(scheduleNormalPackage);
 
     integration('is missing the "homepage" field', () {
-      var package = package("test_pkg", "1.0.0");
-      package.remove("homepage");
-      dir(appPath, [pubspec(package)]).scheduleCreate();
+      var pkg = package("test_pkg", "1.0.0");
+      pkg.remove("homepage");
+      dir(appPath, [pubspec(pkg)]).scheduleCreate();
 
       expectValidationError(pubspecField);
     });
 
     integration('is missing the "description" field', () {
-      var package = package("test_pkg", "1.0.0");
-      package.remove("description");
-      dir(appPath, [pubspec(package)]).scheduleCreate();
+      var pkg = package("test_pkg", "1.0.0");
+      pkg.remove("description");
+      dir(appPath, [pubspec(pkg)]).scheduleCreate();
 
       expectValidationError(pubspecField);
     });
 
     integration('is missing the "author" field', () {
-      var package = package("test_pkg", "1.0.0");
-      package.remove("author");
-      dir(appPath, [pubspec(package)]).scheduleCreate();
+      var pkg = package("test_pkg", "1.0.0");
+      pkg.remove("author");
+      dir(appPath, [pubspec(pkg)]).scheduleCreate();
 
       expectValidationError(pubspecField);
     });
 
     integration('has a single author without an email', () {
-      var package = package("test_pkg", "1.0.0");
-      package["author"] = "Nathan Weizenbaum";
-      dir(appPath, [pubspec(package)]).scheduleCreate();
+      var pkg = package("test_pkg", "1.0.0");
+      pkg["author"] = "Nathan Weizenbaum";
+      dir(appPath, [pubspec(pkg)]).scheduleCreate();
 
       expectValidationWarning(pubspecField);
     });
 
     integration('has one of several authors without an email', () {
-      var package = package("test_pkg", "1.0.0");
-      package.remove("author");
-      package["authors"] = [
+      var pkg = package("test_pkg", "1.0.0");
+      pkg.remove("author");
+      pkg["authors"] = [
         "Bob Nystrom <rnystrom@google.com>",
         "Nathan Weizenbaum",
         "John Messerly <jmesserly@google.com>"
       ];
-      dir(appPath, [pubspec(package)]).scheduleCreate();
+      dir(appPath, [pubspec(pkg)]).scheduleCreate();
 
       expectValidationWarning(pubspecField);
     });
 
     integration('has a single author without a name', () {
-      var package = package("test_pkg", "1.0.0");
-      package["author"] = "<nweiz@google.com>";
-      dir(appPath, [pubspec(package)]).scheduleCreate();
+      var pkg = package("test_pkg", "1.0.0");
+      pkg["author"] = "<nweiz@google.com>";
+      dir(appPath, [pubspec(pkg)]).scheduleCreate();
 
       expectValidationWarning(pubspecField);
     });
 
     integration('has one of several authors without a name', () {
-      var package = package("test_pkg", "1.0.0");
-      package.remove("author");
-      package["authors"] = [
+      var pkg = package("test_pkg", "1.0.0");
+      pkg.remove("author");
+      pkg["authors"] = [
         "Bob Nystrom <rnystrom@google.com>",
         "<nweiz@google.com>",
         "John Messerly <jmesserly@google.com>"
       ];
-      dir(appPath, [pubspec(package)]).scheduleCreate();
+      dir(appPath, [pubspec(pkg)]).scheduleCreate();
 
       expectValidationWarning(pubspecField);
     });
 
     integration('has no LICENSE file', () {
-      file(join(appPath, 'LICENSE'), '').scheduleDelete();
+      file(path.join(appPath, 'LICENSE'), '').scheduleDelete();
       expectValidationError(license);
     });
 
@@ -334,7 +335,7 @@
     });
 
     integration('has a single library named differently than the package', () {
-      file(join(appPath, "lib", "test_pkg.dart"), '').scheduleDelete();
+      file(path.join(appPath, "lib", "test_pkg.dart"), '').scheduleDelete();
       dir(appPath, [
         dir("lib", [file("best_pkg.dart", "int i = 0;")])
       ]).scheduleCreate();
@@ -342,17 +343,17 @@
     });
 
     integration('has no lib directory', () {
-      dir(join(appPath, "lib")).scheduleDelete();
+      dir(path.join(appPath, "lib")).scheduleDelete();
       expectValidationError(lib);
     });
 
     integration('has an empty lib directory', () {
-      file(join(appPath, "lib", "test_pkg.dart"), '').scheduleDelete();
+      file(path.join(appPath, "lib", "test_pkg.dart"), '').scheduleDelete();
       expectValidationError(lib);
     });
 
     integration('has a lib directory containing only src', () {
-      file(join(appPath, "lib", "test_pkg.dart"), '').scheduleDelete();
+      file(path.join(appPath, "lib", "test_pkg.dart"), '').scheduleDelete();
       dir(appPath, [
         dir("lib", [
           dir("src", [file("test_pkg.dart", "int i = 0;")])
diff --git a/utils/tests/pub/version_solver_test.dart b/utils/tests/pub/version_solver_test.dart
index eb37f64..3d4b020 100644
--- a/utils/tests/pub/version_solver_test.dart
+++ b/utils/tests/pub/version_solver_test.dart
@@ -465,11 +465,11 @@
       : _packages = <String, Map<Version, Package>>{};
 
   Future<List<Version>> getVersions(String name, String description) {
-    return fakeAsync(() => _packages[description].keys.toList());
+    return defer(() => _packages[description].keys.toList());
   }
 
   Future<Pubspec> describe(PackageId id) {
-    return fakeAsync(() {
+    return defer(() {
       return _packages[id.name][id.version].pubspec;
     });
   }
@@ -526,15 +526,6 @@
   }
 }
 
-Future fakeAsync(callback()) {
-  var completer = new Completer();
-  Timer.run(() {
-    completer.complete(callback());
-  });
-
-  return completer.future;
-}
-
 Pair<String, Source> parseSource(String name) {
   var match = new RegExp(r"(.*) from (.*)").firstMatch(name);
   if (match == null) return new Pair<String, Source>(name, source1);
