Version 0.3.4.0

svn merge -r 17990:18113 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@18115 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/analyzer-experimental/bin/analyzer.dart b/pkg/analyzer-experimental/bin/analyzer.dart
index da405db..2214490 100644
--- a/pkg/analyzer-experimental/bin/analyzer.dart
+++ b/pkg/analyzer-experimental/bin/analyzer.dart
@@ -7,7 +7,7 @@
 /** The entry point for the analyzer. */
 library analyzer;
 
-//import 'dart:async';
+import 'dart:async';
 import 'dart:io';
 
 import 'package:analyzer-experimental/options.dart';
diff --git a/pkg/analyzer-experimental/example/parser_driver.dart b/pkg/analyzer-experimental/example/parser_driver.dart
new file mode 100644
index 0000000..061a055
--- /dev/null
+++ b/pkg/analyzer-experimental/example/parser_driver.dart
@@ -0,0 +1,60 @@
+#!/usr/bin/env dart
+
+// 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.
+
+import 'package:analyzer-experimental/src/generated/ast.dart';
+import 'package:analyzer-experimental/src/generated/error.dart';
+import 'package:analyzer-experimental/src/generated/java_core.dart';
+import 'package:analyzer-experimental/src/generated/parser.dart';
+import 'package:analyzer-experimental/src/generated/scanner.dart';
+
+import 'dart:io';
+
+
+main() {
+  
+  print('working dir ${new File('.').fullPathSync()}');
+  
+  var args = new Options().arguments;
+  if (args.length == 0) {
+    print('Usage: parser_driver [files_to_parse]');
+    exit(0);
+  }
+  
+  for (var arg in args) {
+    _parse(new File(arg));
+  }
+  
+}
+
+_parse(File file) {
+  var src = file.readAsStringSync();
+  var errorListener = new _ErrorCollector();
+  var scanner = new StringScanner(null, src, errorListener);
+  var token = scanner.tokenize();
+  var parser = new Parser(null, errorListener);
+  var unit = parser.parseCompilationUnit(token);
+  
+  var visitor = new _ASTVisitor();
+  unit.accept(visitor);
+  
+  for (var error in errorListener.errors) {
+    print(error);
+  }
+}
+
+class _ErrorCollector extends AnalysisErrorListener {
+  List<AnalysisError> errors;
+  _ErrorCollector() : errors = new List<AnalysisError>();
+  onError(error) => errors.add(error);
+}
+
+class _ASTVisitor extends GeneralizingASTVisitor {
+  visitNode(ASTNode node) {
+    print('${node.runtimeType} : <"${node.toString()}">');
+    return super.visitNode(node);
+  }
+}
+
diff --git a/pkg/analyzer-experimental/example/scanner_driver.dart b/pkg/analyzer-experimental/example/scanner_driver.dart
new file mode 100644
index 0000000..ab5a46c
--- /dev/null
+++ b/pkg/analyzer-experimental/example/scanner_driver.dart
@@ -0,0 +1,36 @@
+#!/usr/bin/env dart
+
+// 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.
+
+import 'package:analyzer-experimental/src/generated/java_core.dart';
+import 'package:analyzer-experimental/src/generated/scanner.dart';
+
+import 'dart:io';
+
+main() {
+  
+  print('working dir ${new File('.').fullPathSync()}');
+  
+  var args = new Options().arguments;
+  if (args.length == 0) {
+    print('Usage: scanner_driver [files_to_scan]');
+    exit(0);
+  }
+  
+  for (var arg in args) {
+    _scan(new File(arg));
+  }
+  
+}
+
+_scan(File file) {
+  var src = file.readAsStringSync();
+  var scanner = new StringScanner(null, src, null);
+  var token = scanner.tokenize();
+  while (token.type != TokenType.EOF) {
+    print(token);
+    token = token.next;
+  }
+}
diff --git a/pkg/analyzer-experimental/lib/src/generated/ast.dart b/pkg/analyzer-experimental/lib/src/generated/ast.dart
new file mode 100644
index 0000000..4e808bf
--- /dev/null
+++ b/pkg/analyzer-experimental/lib/src/generated/ast.dart
@@ -0,0 +1,11457 @@
+// 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;
+
+import 'dart:collection';
+import 'java_core.dart';
+import 'java_engine.dart';
+import 'error.dart';
+import 'scanner.dart';
+import 'package:analyzer-experimental/src/generated/utilities_dart.dart';
+import 'element.dart' hide Annotation;
+
+/**
+ * The abstract class {@code ASTNode} defines the behavior common to all nodes in the AST structure
+ * for a Dart program.
+ */
+abstract class ASTNode {
+  /**
+   * The parent of the node, or {@code null} if the node is the root of an AST structure.
+   */
+  ASTNode _parent;
+  /**
+   * A comparator that can be used to sort AST nodes in lexical order. In other words,{@code compare} will return a negative value if the offset of the first node is less than the
+   * offset of the second node, zero (0) if the nodes have the same offset, and a positive value if
+   * if the offset of the first node is greater than the offset of the second node.
+   */
+  static Comparator<ASTNode> LEXICAL_ORDER = (ASTNode first, ASTNode second) => second.offset - first.offset;
+  /**
+   * Use the given visitor to visit this node.
+   * @param visitor the visitor that will visit this node
+   * @return the value returned by the visitor as a result of visiting this node
+   */
+  accept(ASTVisitor visitor);
+  /**
+   * Return the first token included in this node's source range.
+   * @return the first token included in this node's source range
+   */
+  Token get beginToken;
+  /**
+   * Return the offset of the character immediately following the last character of this node's
+   * source range. This is equivalent to {@code node.getOffset() + node.getLength()}. For a
+   * compilation unit this will be equal to the length of the unit's source. For synthetic nodes
+   * this will be equivalent to the node's offset (because the length is zero (0) by definition).
+   * @return the offset of the character just past the node's source range
+   */
+  int get end => offset + length;
+  /**
+   * Return the last token included in this node's source range.
+   * @return the last token included in this node's source range
+   */
+  Token get endToken;
+  /**
+   * Return the number of characters in the node's source range.
+   * @return the number of characters in the node's source range
+   */
+  int get length {
+    Token beginToken2 = beginToken;
+    Token endToken3 = endToken;
+    if (beginToken2 == null || endToken3 == null) {
+      return -1;
+    }
+    return endToken3.offset + endToken3.length - beginToken2.offset;
+  }
+  /**
+   * Return the offset from the beginning of the file to the first character in the node's source
+   * range.
+   * @return the offset from the beginning of the file to the first character in the node's source
+   * range
+   */
+  int get offset {
+    Token beginToken3 = beginToken;
+    if (beginToken3 == null) {
+      return -1;
+    }
+    return beginToken.offset;
+  }
+  /**
+   * Return this node's parent node, or {@code null} if this node is the root of an AST structure.
+   * <p>
+   * Note that the relationship between an AST node and its parent node may change over the lifetime
+   * of a node.
+   * @return the parent of this node, or {@code null} if none
+   */
+  ASTNode get parent => _parent;
+  /**
+   * Return the node at the root of this node's AST structure. Note that this method's performance
+   * is linear with respect to the depth of the node in the AST structure (O(depth)).
+   * @return the node at the root of this node's AST structure
+   */
+  ASTNode get root {
+    ASTNode root = this;
+    ASTNode parent3 = parent;
+    while (parent3 != null) {
+      root = parent3;
+      parent3 = root.parent;
+    }
+    return root;
+  }
+  /**
+   * Return {@code true} if this node is a synthetic node. A synthetic node is a node that was
+   * introduced by the parser in order to recover from an error in the code. Synthetic nodes always
+   * have a length of zero ({@code 0}).
+   * @return {@code true} if this node is a synthetic node
+   */
+  bool isSynthetic() => false;
+  /**
+   * Return a textual description of this node in a form approximating valid source. The returned
+   * string will not be valid source primarily in the case where the node itself is not well-formed.
+   * @return the source code equivalent of this node
+   */
+  String toSource() {
+    PrintStringWriter writer = new PrintStringWriter();
+    accept(new ToSourceVisitor(writer));
+    return writer.toString();
+  }
+  String toString() => toSource();
+  /**
+   * Use the given visitor to visit all of the children of this node. The children will be visited
+   * in source order.
+   * @param visitor the visitor that will be used to visit the children of this node
+   */
+  void visitChildren(ASTVisitor<Object> visitor);
+  /**
+   * Make this node the parent of the given child node.
+   * @param child the node that will become a child of this node
+   * @return the node that was made a child of this node
+   */
+  ASTNode becomeParentOf(ASTNode child) {
+    if (child != null) {
+      ASTNode node = child;
+      node.parent2 = this;
+    }
+    return child;
+  }
+  /**
+   * If the given child is not {@code null}, use the given visitor to visit it.
+   * @param child the child to be visited
+   * @param visitor the visitor that will be used to visit the child
+   */
+  void safelyVisitChild(ASTNode child, ASTVisitor<Object> visitor) {
+    if (child != null) {
+      child.accept(visitor);
+    }
+  }
+  /**
+   * 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) {
+    _parent = newParent;
+  }
+}
+/**
+ * The interface {@code ASTVisitor} defines the behavior of objects that can be used to visit an AST
+ * structure.
+ */
+abstract class ASTVisitor<R> {
+  R visitAdjacentStrings(AdjacentStrings node);
+  R visitAnnotation(Annotation node);
+  R visitArgumentDefinitionTest(ArgumentDefinitionTest node);
+  R visitArgumentList(ArgumentList node);
+  R visitAsExpression(AsExpression node);
+  R visitAssertStatement(AssertStatement assertStatement);
+  R visitAssignmentExpression(AssignmentExpression node);
+  R visitBinaryExpression(BinaryExpression node);
+  R visitBlock(Block node);
+  R visitBlockFunctionBody(BlockFunctionBody node);
+  R visitBooleanLiteral(BooleanLiteral node);
+  R visitBreakStatement(BreakStatement node);
+  R visitCascadeExpression(CascadeExpression node);
+  R visitCatchClause(CatchClause node);
+  R visitClassDeclaration(ClassDeclaration node);
+  R visitClassTypeAlias(ClassTypeAlias node);
+  R visitComment(Comment node);
+  R visitCommentReference(CommentReference node);
+  R visitCompilationUnit(CompilationUnit node);
+  R visitConditionalExpression(ConditionalExpression node);
+  R visitConstructorDeclaration(ConstructorDeclaration node);
+  R visitConstructorFieldInitializer(ConstructorFieldInitializer node);
+  R visitConstructorName(ConstructorName node);
+  R visitContinueStatement(ContinueStatement node);
+  R visitDefaultFormalParameter(DefaultFormalParameter node);
+  R visitDoStatement(DoStatement node);
+  R visitDoubleLiteral(DoubleLiteral node);
+  R visitEmptyFunctionBody(EmptyFunctionBody node);
+  R visitEmptyStatement(EmptyStatement node);
+  R visitExportDirective(ExportDirective node);
+  R visitExpressionFunctionBody(ExpressionFunctionBody node);
+  R visitExpressionStatement(ExpressionStatement node);
+  R visitExtendsClause(ExtendsClause node);
+  R visitFieldDeclaration(FieldDeclaration node);
+  R visitFieldFormalParameter(FieldFormalParameter node);
+  R visitForEachStatement(ForEachStatement node);
+  R visitFormalParameterList(FormalParameterList node);
+  R visitForStatement(ForStatement node);
+  R visitFunctionDeclaration(FunctionDeclaration node);
+  R visitFunctionDeclarationStatement(FunctionDeclarationStatement node);
+  R visitFunctionExpression(FunctionExpression node);
+  R visitFunctionExpressionInvocation(FunctionExpressionInvocation node);
+  R visitFunctionTypeAlias(FunctionTypeAlias functionTypeAlias);
+  R visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node);
+  R visitHideCombinator(HideCombinator node);
+  R visitIfStatement(IfStatement node);
+  R visitImplementsClause(ImplementsClause node);
+  R visitImportDirective(ImportDirective node);
+  R visitIndexExpression(IndexExpression node);
+  R visitInstanceCreationExpression(InstanceCreationExpression node);
+  R visitIntegerLiteral(IntegerLiteral node);
+  R visitInterpolationExpression(InterpolationExpression node);
+  R visitInterpolationString(InterpolationString node);
+  R visitIsExpression(IsExpression node);
+  R visitLabel(Label node);
+  R visitLabeledStatement(LabeledStatement node);
+  R visitLibraryDirective(LibraryDirective node);
+  R visitLibraryIdentifier(LibraryIdentifier node);
+  R visitListLiteral(ListLiteral node);
+  R visitMapLiteral(MapLiteral node);
+  R visitMapLiteralEntry(MapLiteralEntry node);
+  R visitMethodDeclaration(MethodDeclaration node);
+  R visitMethodInvocation(MethodInvocation node);
+  R visitNamedExpression(NamedExpression node);
+  R visitNullLiteral(NullLiteral node);
+  R visitParenthesizedExpression(ParenthesizedExpression node);
+  R visitPartDirective(PartDirective node);
+  R visitPartOfDirective(PartOfDirective node);
+  R visitPostfixExpression(PostfixExpression node);
+  R visitPrefixedIdentifier(PrefixedIdentifier node);
+  R visitPrefixExpression(PrefixExpression node);
+  R visitPropertyAccess(PropertyAccess node);
+  R visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node);
+  R visitReturnStatement(ReturnStatement node);
+  R visitScriptTag(ScriptTag node);
+  R visitShowCombinator(ShowCombinator node);
+  R visitSimpleFormalParameter(SimpleFormalParameter node);
+  R visitSimpleIdentifier(SimpleIdentifier node);
+  R visitSimpleStringLiteral(SimpleStringLiteral node);
+  R visitStringInterpolation(StringInterpolation node);
+  R visitSuperConstructorInvocation(SuperConstructorInvocation node);
+  R visitSuperExpression(SuperExpression node);
+  R visitSwitchCase(SwitchCase node);
+  R visitSwitchDefault(SwitchDefault node);
+  R visitSwitchStatement(SwitchStatement node);
+  R visitThisExpression(ThisExpression node);
+  R visitThrowExpression(ThrowExpression node);
+  R visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node);
+  R visitTryStatement(TryStatement node);
+  R visitTypeArgumentList(TypeArgumentList node);
+  R visitTypeName(TypeName node);
+  R visitTypeParameter(TypeParameter node);
+  R visitTypeParameterList(TypeParameterList node);
+  R visitVariableDeclaration(VariableDeclaration node);
+  R visitVariableDeclarationList(VariableDeclarationList node);
+  R visitVariableDeclarationStatement(VariableDeclarationStatement node);
+  R visitWhileStatement(WhileStatement node);
+  R visitWithClause(WithClause node);
+}
+/**
+ * Instances of the class {@code AdjacentStrings} represents two or more string literals that are
+ * implicitly concatenated because of being adjacent (separated only by whitespace).
+ * <p>
+ * While the grammar only allows adjacent strings when all of the strings are of the same kind
+ * (single line or multi-line), this class doesn't enforce that restriction.
+ * <pre>
+ * adjacentStrings ::={@link StringLiteral string} {@link StringLiteral string}+
+ * </pre>
+ */
+class AdjacentStrings extends StringLiteral {
+  /**
+   * The strings that are implicitly concatenated.
+   */
+  NodeList<StringLiteral> _strings;
+  /**
+   * Initialize a newly created list of adjacent strings.
+   * @param strings the strings that are implicitly concatenated
+   */
+  AdjacentStrings(List<StringLiteral> strings) {
+    this._strings = new NodeList<StringLiteral>(this);
+    this._strings.addAll(strings);
+  }
+  accept(ASTVisitor visitor) => visitor.visitAdjacentStrings(this);
+  Token get beginToken => _strings.beginToken;
+  Token get endToken => _strings.endToken;
+  /**
+   * Return the strings that are implicitly concatenated.
+   * @return the strings that are implicitly concatenated
+   */
+  NodeList<StringLiteral> get strings => _strings;
+  void visitChildren(ASTVisitor<Object> visitor) {
+    _strings.accept(visitor);
+  }
+}
+/**
+ * The abstract class {@code AnnotatedNode} defines the behavior of nodes that can be annotated with
+ * both a comment and metadata.
+ */
+abstract class AnnotatedNode extends ASTNode {
+  /**
+   * The documentation comment associated with this node, or {@code null} if this node does not have
+   * a documentation comment associated with it.
+   */
+  Comment _comment;
+  /**
+   * The annotations associated with this node.
+   */
+  NodeList<Annotation> _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._metadata = new NodeList<Annotation>(this);
+    this._comment = becomeParentOf(comment);
+    this._metadata.addAll(metadata);
+  }
+  Token get beginToken {
+    if (_comment == null) {
+      if (_metadata.isEmpty) {
+        return firstTokenAfterCommentAndMetadata;
+      } else {
+        return _metadata.beginToken;
+      }
+    } else if (_metadata.isEmpty) {
+      return _comment.beginToken;
+    }
+    Token commentToken = _comment.beginToken;
+    Token metadataToken = _metadata.beginToken;
+    if (commentToken.offset < metadataToken.offset) {
+      return commentToken;
+    }
+    return metadataToken;
+  }
+  /**
+   * Return the documentation comment associated with this node, or {@code null} if this node does
+   * not have a documentation comment associated with it.
+   * @return the documentation comment associated with this node
+   */
+  Comment get documentationComment => _comment;
+  /**
+   * Return the annotations associated with this node.
+   * @return the annotations associated with this node
+   */
+  NodeList<Annotation> get metadata => _metadata;
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    if (commentIsBeforeAnnotations()) {
+      safelyVisitChild(_comment, visitor);
+      _metadata.accept(visitor);
+    } else {
+      for (ASTNode child in sortedCommentAndAnnotations) {
+        child.accept(visitor);
+      }
+    }
+  }
+  /**
+   * Return the first token following the comment and metadata.
+   * @return the first token following the comment and metadata
+   */
+  Token get firstTokenAfterCommentAndMetadata;
+  /**
+   * Return {@code true} if the comment is lexically before any annotations.
+   * @return {@code true} if the comment is lexically before any annotations
+   */
+  bool commentIsBeforeAnnotations() {
+    if (_comment == null || _metadata.isEmpty) {
+      return true;
+    }
+    Annotation firstAnnotation = _metadata[0];
+    return _comment.offset < firstAnnotation.offset;
+  }
+  /**
+   * Return an array containing the comment and annotations associated with this node, sorted in
+   * lexical order.
+   * @return the comment and annotations associated with this node in the order in which they
+   * appeared in the original source
+   */
+  List<ASTNode> get sortedCommentAndAnnotations {
+    List<ASTNode> childList = new List<ASTNode>();
+    childList.add(_comment);
+    childList.addAll(_metadata);
+    List<ASTNode> children = new List.from(childList);
+    children.sort();
+    return children;
+  }
+}
+/**
+ * Instances of the class {@code Annotation} represent an annotation that can be associated with an
+ * AST node.
+ * <pre>
+ * metadata ::=
+ * annotation
+ * annotation ::=
+ * '@' {@link Identifier qualified} (‘.’ {@link SimpleIdentifier identifier})? {@link ArgumentList arguments}?
+ * </pre>
+ */
+class Annotation extends ASTNode {
+  /**
+   * The at sign that introduced the annotation.
+   */
+  Token _atSign;
+  /**
+   * The name of the class defining the constructor that is being invoked or the name of the field
+   * that is being referenced.
+   */
+  Identifier _name;
+  /**
+   * The period before the constructor name, or {@code null} if this annotation is not the
+   * invocation of a named constructor.
+   */
+  Token _period;
+  /**
+   * The name of the constructor being invoked, or {@code null} if this annotation is not the
+   * invocation of a named constructor.
+   */
+  SimpleIdentifier _constructorName;
+  /**
+   * The arguments to the constructor being invoked, or {@code null} if this annotation is not the
+   * invocation of a constructor.
+   */
+  ArgumentList _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._atSign = atSign;
+    this._name = becomeParentOf(name);
+    this._period = period;
+    this._constructorName = becomeParentOf(constructorName);
+    this._arguments = becomeParentOf(arguments);
+  }
+  accept(ASTVisitor visitor) => visitor.visitAnnotation(this);
+  /**
+   * Return the arguments to the constructor being invoked, or {@code null} if this annotation is
+   * not the invocation of a constructor.
+   * @return the arguments to the constructor being invoked
+   */
+  ArgumentList get arguments => _arguments;
+  /**
+   * Return the at sign that introduced the annotation.
+   * @return the at sign that introduced the annotation
+   */
+  Token get atSign => _atSign;
+  Token get beginToken => _atSign;
+  /**
+   * Return the name of the constructor being invoked, or {@code null} if this annotation is not the
+   * invocation of a named constructor.
+   * @return the name of the constructor being invoked
+   */
+  SimpleIdentifier get constructorName => _constructorName;
+  Token get endToken {
+    if (_arguments != null) {
+      return _arguments.endToken;
+    } else if (_constructorName != null) {
+      return _constructorName.endToken;
+    }
+    return _name.endToken;
+  }
+  /**
+   * Return the name of the class defining the constructor that is being invoked or the name of the
+   * field that is being referenced.
+   * @return the name of the constructor being invoked or the name of the field being referenced
+   */
+  Identifier get name => _name;
+  /**
+   * Return the period before the constructor name, or {@code null} if this annotation is not the
+   * invocation of a named constructor.
+   * @return the period before the constructor name
+   */
+  Token get period => _period;
+  /**
+   * 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);
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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);
+  }
+  /**
+   * 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);
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_name, visitor);
+    safelyVisitChild(_constructorName, visitor);
+    safelyVisitChild(_arguments, visitor);
+  }
+}
+/**
+ * Instances of the class {@code ArgumentDefinitionTest} represent an argument definition test.
+ * <pre>
+ * argumentDefinitionTest ::=
+ * '?' {@link SimpleIdentifier identifier}</pre>
+ */
+class ArgumentDefinitionTest extends Expression {
+  /**
+   * The token representing the question mark.
+   */
+  Token _question;
+  /**
+   * The identifier representing the argument being tested.
+   */
+  SimpleIdentifier _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._question = question;
+    this._identifier = becomeParentOf(identifier);
+  }
+  accept(ASTVisitor visitor) => visitor.visitArgumentDefinitionTest(this);
+  Token get beginToken => _question;
+  Token get endToken => _identifier.endToken;
+  /**
+   * Return the identifier representing the argument being tested.
+   * @return the identifier representing the argument being tested
+   */
+  SimpleIdentifier get identifier => _identifier;
+  /**
+   * Return the token representing the question mark.
+   * @return the token representing the question mark
+   */
+  Token get question => _question;
+  /**
+   * 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);
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_identifier, visitor);
+  }
+}
+/**
+ * Instances of the class {@code ArgumentList} represent a list of arguments in the invocation of a
+ * executable element: a function, method, or constructor.
+ * <pre>
+ * argumentList ::=
+ * '(' arguments? ')'
+ * arguments ::={@link NamedExpression namedArgument} (',' {@link NamedExpression namedArgument})
+ * | {@link Expression expressionList} (',' {@link NamedExpression namedArgument})
+ * </pre>
+ */
+class ArgumentList extends ASTNode {
+  /**
+   * The left parenthesis.
+   */
+  Token _leftParenthesis;
+  /**
+   * The expressions producing the values of the arguments.
+   */
+  NodeList<Expression> _arguments;
+  /**
+   * The right parenthesis.
+   */
+  Token _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._arguments = new NodeList<Expression>(this);
+    this._leftParenthesis = leftParenthesis;
+    this._arguments.addAll(arguments);
+    this._rightParenthesis = rightParenthesis;
+  }
+  accept(ASTVisitor visitor) => visitor.visitArgumentList(this);
+  /**
+   * Return the expressions producing the values of the arguments. Although the language requires
+   * that positional arguments appear before named arguments, this class allows them to be
+   * intermixed.
+   * @return the expressions producing the values of the arguments
+   */
+  NodeList<Expression> get arguments => _arguments;
+  Token get beginToken => _leftParenthesis;
+  Token get endToken => _rightParenthesis;
+  /**
+   * Return the left parenthesis.
+   * @return the left parenthesis
+   */
+  Token get leftParenthesis => _leftParenthesis;
+  /**
+   * Return the right parenthesis.
+   * @return the right parenthesis
+   */
+  Token get rightParenthesis => _rightParenthesis;
+  /**
+   * Set the left parenthesis to the given token.
+   * @param parenthesis the left parenthesis
+   */
+  void set leftParenthesis2(Token parenthesis) {
+    _leftParenthesis = parenthesis;
+  }
+  /**
+   * Set the right parenthesis to the given token.
+   * @param parenthesis the right parenthesis
+   */
+  void set rightParenthesis2(Token parenthesis) {
+    _rightParenthesis = parenthesis;
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    _arguments.accept(visitor);
+  }
+}
+/**
+ * Instances of the class {@code AsExpression} represent an 'as' expression.
+ * <pre>
+ * asExpression ::={@link Expression expression} 'as' {@link TypeName type}</pre>
+ */
+class AsExpression extends Expression {
+  /**
+   * The expression used to compute the value being cast.
+   */
+  Expression _expression;
+  /**
+   * The as operator.
+   */
+  Token _asOperator;
+  /**
+   * The name of the type being cast to.
+   */
+  TypeName _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._expression = becomeParentOf(expression);
+    this._asOperator = isOperator;
+    this._type = becomeParentOf(type);
+  }
+  accept(ASTVisitor visitor) => visitor.visitAsExpression(this);
+  /**
+   * Return the is operator being applied.
+   * @return the is operator being applied
+   */
+  Token get asOperator => _asOperator;
+  Token get beginToken => _expression.beginToken;
+  Token get endToken => _type.endToken;
+  /**
+   * Return the expression used to compute the value being cast.
+   * @return the expression used to compute the value being cast
+   */
+  Expression get expression => _expression;
+  /**
+   * Return the name of the type being cast to.
+   * @return the name of the type being cast to
+   */
+  TypeName get type => _type;
+  /**
+   * 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;
+  }
+  /**
+   * 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);
+  }
+  /**
+   * 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) {
+    this._type = becomeParentOf(name);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_expression, visitor);
+    safelyVisitChild(_type, visitor);
+  }
+}
+/**
+ * Instances of the class {@code AssertStatement} represent an assert statement.
+ * <pre>
+ * assertStatement ::=
+ * 'assert' '(' {@link Expression conditionalExpression} ')' ';'
+ * </pre>
+ */
+class AssertStatement extends Statement {
+  /**
+   * The token representing the 'assert' keyword.
+   */
+  Token _keyword;
+  /**
+   * The left parenthesis.
+   */
+  Token _leftParenthesis;
+  /**
+   * The condition that is being asserted to be {@code true}.
+   */
+  Expression _condition;
+  /**
+   * The right parenthesis.
+   */
+  Token _rightParenthesis;
+  /**
+   * The semicolon terminating the statement.
+   */
+  Token _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._keyword = keyword;
+    this._leftParenthesis = leftParenthesis;
+    this._condition = becomeParentOf(condition);
+    this._rightParenthesis = rightParenthesis;
+    this._semicolon = semicolon;
+  }
+  accept(ASTVisitor visitor) => visitor.visitAssertStatement(this);
+  Token get beginToken => _keyword;
+  /**
+   * Return the condition that is being asserted to be {@code true}.
+   * @return the condition that is being asserted to be {@code true}
+   */
+  Expression get condition => _condition;
+  Token get endToken => _semicolon;
+  /**
+   * Return the token representing the 'assert' keyword.
+   * @return the token representing the 'assert' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * Return the left parenthesis.
+   * @return the left parenthesis
+   */
+  Token get leftParenthesis => _leftParenthesis;
+  /**
+   * Return the right parenthesis.
+   * @return the right parenthesis
+   */
+  Token get rightParenthesis => _rightParenthesis;
+  /**
+   * Return the semicolon terminating the statement.
+   * @return the semicolon terminating the statement
+   */
+  Token get semicolon => _semicolon;
+  /**
+   * 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);
+  }
+  /**
+   * 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;
+  }
+  /**
+   * Set the left parenthesis to the given token.
+   * @param the left parenthesis
+   */
+  void set leftParenthesis3(Token leftParenthesis) {
+    this._leftParenthesis = leftParenthesis;
+  }
+  /**
+   * Set the right parenthesis to the given token.
+   * @param rightParenthesis the right parenthesis
+   */
+  void set rightParenthesis3(Token rightParenthesis) {
+    this._rightParenthesis = rightParenthesis;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_condition, visitor);
+  }
+}
+/**
+ * Instances of the class {@code AssignmentExpression} represent an assignment expression.
+ * <pre>
+ * assignmentExpression ::={@link Expression leftHandSide} {@link Token operator} {@link Expression rightHandSide}</pre>
+ */
+class AssignmentExpression extends Expression {
+  /**
+   * The expression used to compute the left hand side.
+   */
+  Expression _leftHandSide;
+  /**
+   * The assignment operator being applied.
+   */
+  Token _operator;
+  /**
+   * The expression used to compute the right hand side.
+   */
+  Expression _rightHandSide;
+  /**
+   * The element associated with the operator, or {@code null} if the AST structure has not been
+   * resolved, if the operator is not a compound operator, or if the operator could not be resolved.
+   */
+  MethodElement _element;
+  /**
+   * 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._leftHandSide = becomeParentOf(leftHandSide);
+    this._operator = operator;
+    this._rightHandSide = becomeParentOf(rightHandSide);
+  }
+  accept(ASTVisitor visitor) => visitor.visitAssignmentExpression(this);
+  Token get beginToken => _leftHandSide.beginToken;
+  /**
+   * Return the element associated with the operator, or {@code null} if the AST structure has not
+   * been resolved, if the operator is not a compound operator, or if the operator could not be
+   * resolved. One example of the latter case is an operator that is not defined for the type of the
+   * left-hand operand.
+   * @return the element associated with the operator
+   */
+  MethodElement get element => _element;
+  Token get endToken => _rightHandSide.endToken;
+  /**
+   * Set the expression used to compute the left hand side to the given expression.
+   * @return the expression used to compute the left hand side
+   */
+  Expression get leftHandSide => _leftHandSide;
+  /**
+   * Return the assignment operator being applied.
+   * @return the assignment operator being applied
+   */
+  Token get operator => _operator;
+  /**
+   * Return the expression used to compute the right hand side.
+   * @return the expression used to compute the right hand side
+   */
+  Expression get rightHandSide => _rightHandSide;
+  /**
+   * 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;
+  }
+  /**
+   * 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) {
+    _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;
+  }
+  /**
+   * 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) {
+    _rightHandSide = becomeParentOf(expression);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_leftHandSide, visitor);
+    safelyVisitChild(_rightHandSide, visitor);
+  }
+}
+/**
+ * Instances of the class {@code BinaryExpression} represent a binary (infix) expression.
+ * <pre>
+ * binaryExpression ::={@link Expression leftOperand} {@link Token operator} {@link Expression rightOperand}</pre>
+ */
+class BinaryExpression extends Expression {
+  /**
+   * The expression used to compute the left operand.
+   */
+  Expression _leftOperand;
+  /**
+   * The binary operator being applied.
+   */
+  Token _operator;
+  /**
+   * The expression used to compute the right operand.
+   */
+  Expression _rightOperand;
+  /**
+   * The element associated with the operator, or {@code null} if the AST structure has not been
+   * resolved, if the operator is not user definable, or if the operator could not be resolved.
+   */
+  MethodElement _element;
+  /**
+   * 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._leftOperand = becomeParentOf(leftOperand);
+    this._operator = operator;
+    this._rightOperand = becomeParentOf(rightOperand);
+  }
+  accept(ASTVisitor visitor) => visitor.visitBinaryExpression(this);
+  Token get beginToken => _leftOperand.beginToken;
+  /**
+   * Return the element associated with the operator, or {@code null} if the AST structure has not
+   * been resolved, if the operator is not user definable, or if the operator could not be resolved.
+   * One example of the latter case is an operator that is not defined for the type of the left-hand
+   * operand.
+   * @return the element associated with the operator
+   */
+  MethodElement get element => _element;
+  Token get endToken => _rightOperand.endToken;
+  /**
+   * Return the expression used to compute the left operand.
+   * @return the expression used to compute the left operand
+   */
+  Expression get leftOperand => _leftOperand;
+  /**
+   * Return the binary operator being applied.
+   * @return the binary operator being applied
+   */
+  Token get operator => _operator;
+  /**
+   * Return the expression used to compute the right operand.
+   * @return the expression used to compute the right operand
+   */
+  Expression get rightOperand => _rightOperand;
+  /**
+   * 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;
+  }
+  /**
+   * 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) {
+    _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;
+  }
+  /**
+   * 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) {
+    _rightOperand = becomeParentOf(expression);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_leftOperand, visitor);
+    safelyVisitChild(_rightOperand, visitor);
+  }
+}
+/**
+ * Instances of the class {@code Block} represent a sequence of statements.
+ * <pre>
+ * block ::=
+ * '{' statement* '}'
+ * </pre>
+ */
+class Block extends Statement {
+  /**
+   * The left curly bracket.
+   */
+  Token _leftBracket;
+  /**
+   * The statements contained in the block.
+   */
+  NodeList<Statement> _statements;
+  /**
+   * The right curly bracket.
+   */
+  Token _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._statements = new NodeList<Statement>(this);
+    this._leftBracket = leftBracket;
+    this._statements.addAll(statements);
+    this._rightBracket = rightBracket;
+  }
+  accept(ASTVisitor visitor) => visitor.visitBlock(this);
+  Token get beginToken => _leftBracket;
+  Token get endToken => _rightBracket;
+  /**
+   * Return the left curly bracket.
+   * @return the left curly bracket
+   */
+  Token get leftBracket => _leftBracket;
+  /**
+   * Return the right curly bracket.
+   * @return the right curly bracket
+   */
+  Token get rightBracket => _rightBracket;
+  /**
+   * Return the statements contained in the block.
+   * @return the statements contained in the block
+   */
+  NodeList<Statement> get statements => _statements;
+  /**
+   * Set the left curly bracket to the given token.
+   * @param leftBracket the left curly bracket
+   */
+  void set leftBracket2(Token leftBracket) {
+    this._leftBracket = leftBracket;
+  }
+  /**
+   * Set the right curly bracket to the given token.
+   * @param rightBracket the right curly bracket
+   */
+  void set rightBracket2(Token rightBracket) {
+    this._rightBracket = rightBracket;
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    _statements.accept(visitor);
+  }
+}
+/**
+ * Instances of the class {@code BlockFunctionBody} represent a function body that consists of a
+ * block of statements.
+ * <pre>
+ * blockFunctionBody ::={@link Block block}</pre>
+ */
+class BlockFunctionBody extends FunctionBody {
+  /**
+   * The block representing the body of the function.
+   */
+  Block _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._block = becomeParentOf(block);
+  }
+  accept(ASTVisitor visitor) => visitor.visitBlockFunctionBody(this);
+  Token get beginToken => _block.beginToken;
+  /**
+   * Return the block representing the body of the function.
+   * @return the block representing the body of the function
+   */
+  Block get block => _block;
+  Token get endToken => _block.endToken;
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_block, visitor);
+  }
+}
+/**
+ * Instances of the class {@code BooleanLiteral} represent a boolean literal expression.
+ * <pre>
+ * booleanLiteral ::=
+ * 'false' | 'true'
+ * </pre>
+ */
+class BooleanLiteral extends Literal {
+  /**
+   * The token representing the literal.
+   */
+  Token _literal;
+  /**
+   * The value of the literal.
+   */
+  bool _value = false;
+  /**
+   * 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._literal = literal;
+    this._value = value;
+  }
+  accept(ASTVisitor visitor) => visitor.visitBooleanLiteral(this);
+  Token get beginToken => _literal;
+  Token get endToken => _literal;
+  /**
+   * Return the token representing the literal.
+   * @return the token representing the literal
+   */
+  Token get literal => _literal;
+  /**
+   * Return the value of the literal.
+   * @return the value of the literal
+   */
+  bool get value => _value;
+  bool isSynthetic() => _literal.isSynthetic();
+  /**
+   * 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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+  }
+}
+/**
+ * Instances of the class {@code BreakStatement} represent a break statement.
+ * <pre>
+ * breakStatement ::=
+ * 'break' {@link SimpleIdentifier label}? ';'
+ * </pre>
+ */
+class BreakStatement extends Statement {
+  /**
+   * The token representing the 'break' keyword.
+   */
+  Token _keyword;
+  /**
+   * The label associated with the statement, or {@code null} if there is no label.
+   */
+  SimpleIdentifier _label;
+  /**
+   * The semicolon terminating the statement.
+   */
+  Token _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._keyword = keyword;
+    this._label = becomeParentOf(label);
+    this._semicolon = semicolon;
+  }
+  accept(ASTVisitor visitor) => visitor.visitBreakStatement(this);
+  Token get beginToken => _keyword;
+  Token get endToken => _semicolon;
+  /**
+   * Return the token representing the 'break' keyword.
+   * @return the token representing the 'break' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * Return the label associated with the statement, or {@code null} if there is no label.
+   * @return the label associated with the statement
+   */
+  SimpleIdentifier get label => _label;
+  /**
+   * Return the semicolon terminating the statement.
+   * @return the semicolon terminating the statement
+   */
+  Token get semicolon => _semicolon;
+  /**
+   * 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;
+  }
+  /**
+   * Set the label associated with the statement to the given identifier.
+   * @param identifier the label associated with the statement
+   */
+  void set label2(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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_label, visitor);
+  }
+}
+/**
+ * Instances of the class {@code CascadeExpression} represent a sequence of cascaded expressions:
+ * expressions that share a common target. There are three kinds of expressions that can be used in
+ * a cascade expression: {@link IndexExpression}, {@link MethodInvocation} and{@link PropertyAccess}.
+ * <pre>
+ * cascadeExpression ::={@link Expression conditionalExpression} cascadeSection
+ * cascadeSection ::=
+ * '..'  (cascadeSelector arguments*) (assignableSelector arguments*)* (assignmentOperator expressionWithoutCascade)?
+ * cascadeSelector ::=
+ * '[ ' expression '] '
+ * | identifier
+ * </pre>
+ */
+class CascadeExpression extends Expression {
+  /**
+   * The target of the cascade sections.
+   */
+  Expression _target;
+  /**
+   * The cascade sections sharing the common target.
+   */
+  NodeList<Expression> _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._cascadeSections = new NodeList<Expression>(this);
+    this._target = becomeParentOf(target);
+    this._cascadeSections.addAll(cascadeSections);
+  }
+  accept(ASTVisitor visitor) => visitor.visitCascadeExpression(this);
+  Token get beginToken => _target.beginToken;
+  /**
+   * Return the cascade sections sharing the common target.
+   * @return the cascade sections sharing the common target
+   */
+  NodeList<Expression> get cascadeSections => _cascadeSections;
+  Token get endToken => _cascadeSections.endToken;
+  /**
+   * Return the target of the cascade sections.
+   * @return the target of the cascade sections
+   */
+  Expression get target => _target;
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_target, visitor);
+    _cascadeSections.accept(visitor);
+  }
+}
+/**
+ * Instances of the class {@code CatchClause} represent a catch clause within a try statement.
+ * <pre>
+ * onPart ::=
+ * catchPart {@link Block block}| 'on' type catchPart? {@link Block block}catchPart ::=
+ * 'catch' '(' {@link SimpleIdentifier exceptionParameter} (',' {@link SimpleIdentifier stackTraceParameter})? ')'
+ * </pre>
+ */
+class CatchClause extends ASTNode {
+  /**
+   * The token representing the 'on' keyword, or {@code null} if there is no 'on' keyword.
+   */
+  Token _onKeyword;
+  /**
+   * The type of exceptions caught by this catch clause, or {@code null} if this catch clause
+   * catches every type of exception.
+   */
+  TypeName _exceptionType;
+  /**
+   * The token representing the 'catch' keyword, or {@code null} if there is no 'catch' keyword.
+   */
+  Token _catchKeyword;
+  /**
+   * The left parenthesis.
+   */
+  Token _leftParenthesis;
+  /**
+   * The parameter whose value will be the exception that was thrown.
+   */
+  SimpleIdentifier _exceptionParameter;
+  /**
+   * The comma separating the exception parameter from the stack trace parameter.
+   */
+  Token _comma;
+  /**
+   * The parameter whose value will be the stack trace associated with the exception.
+   */
+  SimpleIdentifier _stackTraceParameter;
+  /**
+   * The right parenthesis.
+   */
+  Token _rightParenthesis;
+  /**
+   * The body of the catch block.
+   */
+  Block _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._onKeyword = onKeyword;
+    this._exceptionType = becomeParentOf(exceptionType);
+    this._catchKeyword = catchKeyword;
+    this._leftParenthesis = leftParenthesis;
+    this._exceptionParameter = becomeParentOf(exceptionParameter);
+    this._comma = comma;
+    this._stackTraceParameter = becomeParentOf(stackTraceParameter);
+    this._rightParenthesis = rightParenthesis;
+    this._body = becomeParentOf(body);
+  }
+  accept(ASTVisitor visitor) => visitor.visitCatchClause(this);
+  Token get beginToken {
+    if (_onKeyword != null) {
+      return _onKeyword;
+    }
+    return _catchKeyword;
+  }
+  /**
+   * Return the body of the catch block.
+   * @return the body of the catch block
+   */
+  Block get body => _body;
+  /**
+   * Return the token representing the 'catch' keyword, or {@code null} if there is no 'catch'
+   * keyword.
+   * @return the token representing the 'catch' keyword
+   */
+  Token get catchKeyword => _catchKeyword;
+  /**
+   * Return the comma.
+   * @return the comma
+   */
+  Token get comma => _comma;
+  Token get endToken => _body.endToken;
+  /**
+   * Return the parameter whose value will be the exception that was thrown.
+   * @return the parameter whose value will be the exception that was thrown
+   */
+  SimpleIdentifier get exceptionParameter => _exceptionParameter;
+  /**
+   * Return the type of exceptions caught by this catch clause, or {@code null} if this catch clause
+   * catches every type of exception.
+   * @return the type of exceptions caught by this catch clause
+   */
+  TypeName get exceptionType => _exceptionType;
+  /**
+   * Return the left parenthesis.
+   * @return the left parenthesis
+   */
+  Token get leftParenthesis => _leftParenthesis;
+  /**
+   * Return the token representing the 'on' keyword, or {@code null} if there is no 'on' keyword.
+   * @return the token representing the 'on' keyword
+   */
+  Token get onKeyword => _onKeyword;
+  /**
+   * Return the right parenthesis.
+   * @return the right parenthesis
+   */
+  Token get rightParenthesis => _rightParenthesis;
+  /**
+   * Return the parameter whose value will be the stack trace associated with the exception.
+   * @return the parameter whose value will be the stack trace associated with the exception
+   */
+  SimpleIdentifier get stackTraceParameter => _stackTraceParameter;
+  /**
+   * Set the body of the catch block to the given block.
+   * @param block the body of the catch block
+   */
+  void set body2(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;
+  }
+  /**
+   * Set the comma to the given token.
+   * @param comma the comma
+   */
+  void set comma2(Token comma) {
+    this._comma = comma;
+  }
+  /**
+   * 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) {
+    _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;
+  }
+  /**
+   * Set the left parenthesis to the given token.
+   * @param parenthesis the left parenthesis
+   */
+  void set leftParenthesis4(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;
+  }
+  /**
+   * Set the right parenthesis to the given token.
+   * @param parenthesis the right parenthesis
+   */
+  void set rightParenthesis4(Token parenthesis) {
+    _rightParenthesis = parenthesis;
+  }
+  /**
+   * Set the parameter whose value will be the stack trace associated with the exception to the
+   * given parameter.
+   * @param parameter the parameter whose value will be the stack trace associated with the
+   * exception
+   */
+  void set stackTraceParameter2(SimpleIdentifier parameter) {
+    _stackTraceParameter = becomeParentOf(parameter);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_exceptionType, visitor);
+    safelyVisitChild(_exceptionParameter, visitor);
+    safelyVisitChild(_stackTraceParameter, visitor);
+    safelyVisitChild(_body, visitor);
+  }
+}
+/**
+ * Instances of the class {@code ClassDeclaration} represent the declaration of a class.
+ * <pre>
+ * classDeclaration ::=
+ * 'abstract'? 'class' {@link SimpleIdentifier name} {@link TypeParameterList typeParameterList}?
+ * ({@link ExtendsClause extendsClause} {@link WithClause withClause}?)?{@link ImplementsClause implementsClause}?
+ * '{' {@link ClassMember classMember}* '}'
+ * </pre>
+ */
+class ClassDeclaration extends CompilationUnitMember {
+  /**
+   * The 'abstract' keyword, or {@code null} if the keyword was absent.
+   */
+  Token _abstractKeyword;
+  /**
+   * The token representing the 'class' keyword.
+   */
+  Token _classKeyword;
+  /**
+   * The name of the class being declared.
+   */
+  SimpleIdentifier _name;
+  /**
+   * The type parameters for the class, or {@code null} if the class does not have any type
+   * parameters.
+   */
+  TypeParameterList _typeParameters;
+  /**
+   * The extends clause for the class, or {@code null} if the class does not extend any other class.
+   */
+  ExtendsClause _extendsClause;
+  /**
+   * The with clause for the class, or {@code null} if the class does not have a with clause.
+   */
+  WithClause _withClause;
+  /**
+   * The implements clause for the class, or {@code null} if the class does not implement any
+   * interfaces.
+   */
+  ImplementsClause _implementsClause;
+  /**
+   * The left curly bracket.
+   */
+  Token _leftBracket;
+  /**
+   * The members defined by the class.
+   */
+  NodeList<ClassMember> _members;
+  /**
+   * The right curly bracket.
+   */
+  Token _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) : super(comment, metadata) {
+    this._members = new NodeList<ClassMember>(this);
+    this._abstractKeyword = abstractKeyword;
+    this._classKeyword = classKeyword;
+    this._name = becomeParentOf(name);
+    this._typeParameters = becomeParentOf(typeParameters);
+    this._extendsClause = becomeParentOf(extendsClause);
+    this._withClause = becomeParentOf(withClause);
+    this._implementsClause = becomeParentOf(implementsClause);
+    this._leftBracket = leftBracket;
+    this._members.addAll(members);
+    this._rightBracket = rightBracket;
+  }
+  accept(ASTVisitor visitor) => visitor.visitClassDeclaration(this);
+  /**
+   * Return the 'abstract' keyword, or {@code null} if the keyword was absent.
+   * @return the 'abstract' keyword
+   */
+  Token get abstractKeyword => _abstractKeyword;
+  /**
+   * Return the token representing the 'class' keyword.
+   * @return the token representing the 'class' keyword
+   */
+  Token get classKeyword => _classKeyword;
+  /**
+   * @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;
+  Token get endToken => _rightBracket;
+  /**
+   * Return the extends clause for this class, or {@code null} if the class does not extend any
+   * other class.
+   * @return the extends clause for this class
+   */
+  ExtendsClause get extendsClause => _extendsClause;
+  /**
+   * Return the implements clause for the class, or {@code null} if the class does not implement any
+   * interfaces.
+   * @return the implements clause for the class
+   */
+  ImplementsClause get implementsClause => _implementsClause;
+  /**
+   * Return the left curly bracket.
+   * @return the left curly bracket
+   */
+  Token get leftBracket => _leftBracket;
+  /**
+   * Return the members defined by the class.
+   * @return the members defined by the class
+   */
+  NodeList<ClassMember> get members => _members;
+  /**
+   * Return the name of the class being declared.
+   * @return the name of the class being declared
+   */
+  SimpleIdentifier get name => _name;
+  /**
+   * Return the right curly bracket.
+   * @return the right curly bracket
+   */
+  Token get rightBracket => _rightBracket;
+  /**
+   * Return the type parameters for the class, or {@code null} if the class does not have any type
+   * parameters.
+   * @return the type parameters for the class
+   */
+  TypeParameterList get typeParameters => _typeParameters;
+  /**
+   * Return the with clause for the class, or {@code null} if the class does not have a with clause.
+   * @return the with clause for the class
+   */
+  WithClause get withClause => _withClause;
+  /**
+   * Set the 'abstract' keyword to the given keyword.
+   * @param abstractKeyword the 'abstract' keyword
+   */
+  void set abstractKeyword2(Token abstractKeyword) {
+    this._abstractKeyword = abstractKeyword;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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);
+  }
+  /**
+   * 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);
+  }
+  /**
+   * Set the left curly bracket to the given token.
+   * @param leftBracket the left curly bracket
+   */
+  void set leftBracket3(Token leftBracket) {
+    this._leftBracket = leftBracket;
+  }
+  /**
+   * 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) {
+    _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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(documentationComment, visitor);
+    safelyVisitChild(_name, visitor);
+    safelyVisitChild(_typeParameters, visitor);
+    safelyVisitChild(_extendsClause, visitor);
+    safelyVisitChild(_withClause, visitor);
+    safelyVisitChild(_implementsClause, visitor);
+    members.accept(visitor);
+  }
+  Token get firstTokenAfterCommentAndMetadata {
+    if (_abstractKeyword != null) {
+      return _abstractKeyword;
+    }
+    return _classKeyword;
+  }
+}
+/**
+ * The abstract class {@code ClassMember} defines the behavior common to nodes that declare a name
+ * within the scope of a class.
+ */
+abstract class ClassMember extends Declaration {
+  /**
+   * 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) : super(comment, metadata) {
+  }
+}
+/**
+ * Instances of the class {@code ClassTypeAlias} represent a class type alias.
+ * <pre>
+ * classTypeAlias ::={@link SimpleIdentifier identifier} {@link TypeParameterList typeParameters}? '=' 'abstract'? mixinApplication
+ * mixinApplication ::={@link TypeName superclass} {@link WithClause withClause} {@link ImplementsClause implementsClause}? ';'
+ * </pre>
+ */
+class ClassTypeAlias extends TypeAlias {
+  /**
+   * The name of the class being declared.
+   */
+  SimpleIdentifier _name;
+  /**
+   * The type parameters for the class, or {@code null} if the class does not have any type
+   * parameters.
+   */
+  TypeParameterList _typeParameters;
+  /**
+   * The token for the '=' separating the name from the definition.
+   */
+  Token _equals;
+  /**
+   * The token for the 'abstract' keyword, or {@code null} if this is not defining an abstract
+   * class.
+   */
+  Token _abstractKeyword;
+  /**
+   * The name of the superclass of the class being declared.
+   */
+  TypeName _superclass;
+  /**
+   * The with clause for this class.
+   */
+  WithClause _withClause;
+  /**
+   * The implements clause for this class, or {@code null} if there is no implements clause.
+   */
+  ImplementsClause _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) : super(comment, metadata, keyword, semicolon) {
+    this._name = becomeParentOf(name);
+    this._typeParameters = becomeParentOf(typeParameters);
+    this._equals = equals;
+    this._abstractKeyword = abstractKeyword;
+    this._superclass = becomeParentOf(superclass);
+    this._withClause = becomeParentOf(withClause);
+    this._implementsClause = becomeParentOf(implementsClause);
+  }
+  accept(ASTVisitor visitor) => visitor.visitClassTypeAlias(this);
+  /**
+   * Return the token for the 'abstract' keyword, or {@code null} if this is not defining an
+   * abstract class.
+   * @return the token for the 'abstract' keyword
+   */
+  Token get abstractKeyword => _abstractKeyword;
+  /**
+   * Return the {@link ClassElement} associated with this type alias, or {@code null} if the AST
+   * structure has not been resolved.
+   * @return the {@link ClassElement} associated with this type alias
+   */
+  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
+   */
+  Token get equals => _equals;
+  /**
+   * Return the implements clause for this class, or {@code null} if there is no implements clause.
+   * @return the implements clause for this class
+   */
+  ImplementsClause get implementsClause => _implementsClause;
+  /**
+   * Return the name of the class being declared.
+   * @return the name of the class being declared
+   */
+  SimpleIdentifier get name => _name;
+  /**
+   * Return the name of the superclass of the class being declared.
+   * @return the name of the superclass of the class being declared
+   */
+  TypeName get superclass => _superclass;
+  /**
+   * Return the type parameters for the class, or {@code null} if the class does not have any type
+   * parameters.
+   * @return the type parameters for the class
+   */
+  TypeParameterList get typeParameters => _typeParameters;
+  /**
+   * Return the with clause for this class.
+   * @return the with clause for this class
+   */
+  WithClause get withClause => _withClause;
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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);
+  }
+  /**
+   * 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);
+  }
+  /**
+   * 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);
+  }
+  /**
+   * 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);
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_name, visitor);
+    safelyVisitChild(_typeParameters, visitor);
+    safelyVisitChild(_superclass, visitor);
+    safelyVisitChild(_withClause, visitor);
+    safelyVisitChild(_implementsClause, visitor);
+  }
+}
+/**
+ * Instances of the class {@code Combinator} represent the combinator associated with an import
+ * directive.
+ * <pre>
+ * combinator ::={@link HideCombinator hideCombinator}| {@link ShowCombinator showCombinator}</pre>
+ */
+abstract class Combinator extends ASTNode {
+  /**
+   * The keyword specifying what kind of processing is to be done on the imported names.
+   */
+  Token _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._keyword = keyword;
+  }
+  Token get beginToken => _keyword;
+  /**
+   * Return the keyword specifying what kind of processing is to be done on the imported names.
+   * @return the keyword specifying what kind of processing is to be done on the imported names
+   */
+  Token get keyword => _keyword;
+  /**
+   * Set the keyword specifying what kind of processing is to be done on the imported names to the
+   * given token.
+   * @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;
+  }
+}
+/**
+ * Instances of the class {@code Comment} represent a comment within the source code.
+ * <pre>
+ * comment ::=
+ * endOfLineComment
+ * | blockComment
+ * | documentationComment
+ * endOfLineComment ::=
+ * '//' (CHARACTER - EOL)* EOL
+ * blockComment ::=
+ * '/ *' CHARACTER* '&#42;/'
+ * documentationComment ::=
+ * '/ **' (CHARACTER | {@link CommentReference commentReference})* '&#42;/'
+ * | ('///' (CHARACTER - EOL)* EOL)+
+ * </pre>
+ */
+class Comment extends ASTNode {
+  /**
+   * Create a block comment.
+   * @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);
+  /**
+   * 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>());
+  /**
+   * 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);
+  /**
+   * 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);
+  /**
+   * The tokens representing the comment.
+   */
+  List<Token> _tokens;
+  /**
+   * The type of the comment.
+   */
+  CommentType _type;
+  /**
+   * The references embedded within the documentation comment. This list will be empty unless this
+   * is a documentation comment that has references embedded within it.
+   */
+  NodeList<CommentReference> _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._references = new NodeList<CommentReference>(this);
+    this._tokens = tokens;
+    this._type = type;
+    this._references.addAll(references);
+  }
+  accept(ASTVisitor visitor) => visitor.visitComment(this);
+  Token get beginToken => _tokens[0];
+  Token get endToken => _tokens[_tokens.length - 1];
+  /**
+   * Return the references embedded within the documentation comment.
+   * @return the references embedded within the documentation comment
+   */
+  NodeList<CommentReference> get references => _references;
+  /**
+   * Return {@code true} if this is a block comment.
+   * @return {@code true} if this is a block comment
+   */
+  bool isBlock() => _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;
+  /**
+   * 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;
+  void visitChildren(ASTVisitor<Object> visitor) {
+    _references.accept(visitor);
+  }
+}
+/**
+ * The enumeration {@code CommentType} encodes all the different types of comments that are
+ * recognized by the parser.
+ */
+class CommentType {
+  /**
+   * An end-of-line comment.
+   */
+  static final CommentType END_OF_LINE = new CommentType('END_OF_LINE', 0);
+  /**
+   * A block comment.
+   */
+  static final CommentType BLOCK = new CommentType('BLOCK', 1);
+  /**
+   * A documentation comment.
+   */
+  static final CommentType DOCUMENTATION = new CommentType('DOCUMENTATION', 2);
+  static final List<CommentType> values = [END_OF_LINE, BLOCK, DOCUMENTATION];
+  final String __name;
+  final int __ordinal;
+  CommentType(this.__name, this.__ordinal) {
+  }
+  String toString() => __name;
+}
+/**
+ * Instances of the class {@code CommentReference} represent a reference to a Dart element that is
+ * found within a documentation comment.
+ * <pre>
+ * commentReference ::=
+ * '[' 'new'? {@link Identifier identifier} ']'
+ * </pre>
+ */
+class CommentReference extends ASTNode {
+  /**
+   * The token representing the 'new' keyword, or {@code null} if there was no 'new' keyword.
+   */
+  Token _newKeyword;
+  /**
+   * The identifier being referenced.
+   */
+  Identifier _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._newKeyword = newKeyword;
+    this._identifier = becomeParentOf(identifier);
+  }
+  accept(ASTVisitor visitor) => visitor.visitCommentReference(this);
+  Token get beginToken => _identifier.beginToken;
+  Token get endToken => _identifier.endToken;
+  /**
+   * Return the identifier being referenced.
+   * @return the identifier being referenced
+   */
+  Identifier get identifier => _identifier;
+  /**
+   * Return the token representing the 'new' keyword, or {@code null} if there was no 'new' keyword.
+   * @return the token representing the 'new' keyword
+   */
+  Token get newKeyword => _newKeyword;
+  /**
+   * Set the identifier being referenced to the given identifier.
+   * @param identifier the identifier being referenced
+   */
+  void set identifier3(Identifier identifier) {
+    identifier = becomeParentOf(identifier);
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_identifier, visitor);
+  }
+}
+/**
+ * Instances of the class {@code CompilationUnit} represent a compilation unit.
+ * <p>
+ * While the grammar restricts the order of the directives and declarations within a compilation
+ * unit, this class does not enforce those restrictions. In particular, the children of a
+ * compilation unit will be visited in lexical order even if lexical order does not conform to the
+ * restrictions of the grammar.
+ * <pre>
+ * compilationUnit ::=
+ * directives declarations
+ * directives ::={@link ScriptTag scriptTag}? {@link LibraryDirective libraryDirective}? namespaceDirective* {@link PartDirective partDirective}| {@link PartOfDirective partOfDirective}namespaceDirective ::={@link ImportDirective importDirective}| {@link ExportDirective exportDirective}declarations ::={@link CompilationUnitMember compilationUnitMember}</pre>
+ */
+class CompilationUnit extends ASTNode {
+  /**
+   * The first token in the token stream that was parsed to form this compilation unit.
+   */
+  Token _beginToken;
+  /**
+   * The script tag at the beginning of the compilation unit, or {@code null} if there is no script
+   * tag in this compilation unit.
+   */
+  ScriptTag _scriptTag;
+  /**
+   * The directives contained in this compilation unit.
+   */
+  NodeList<Directive> _directives;
+  /**
+   * The declarations contained in this compilation unit.
+   */
+  NodeList<CompilationUnitMember> _declarations;
+  /**
+   * The last token in the token stream that was parsed to form this compilation unit. This token
+   * should always have a type of {@link TokenType.EOF}.
+   */
+  Token _endToken;
+  /**
+   * The element associated with this compilation unit, or {@code null} if the AST structure has not
+   * been resolved.
+   */
+  CompilationUnitElement _element;
+  /**
+   * The syntax errors encountered when the receiver was parsed.
+   */
+  List<AnalysisError> _syntacticErrors;
+  /**
+   * 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._directives = new NodeList<Directive>(this);
+    this._declarations = new NodeList<CompilationUnitMember>(this);
+    this._beginToken = beginToken;
+    this._scriptTag = becomeParentOf(scriptTag);
+    this._directives.addAll(directives);
+    this._declarations.addAll(declarations);
+    this._endToken = endToken;
+  }
+  accept(ASTVisitor visitor) => visitor.visitCompilationUnit(this);
+  Token get beginToken => _beginToken;
+  /**
+   * Return the declarations contained in this compilation unit.
+   * @return the declarations contained in this compilation unit
+   */
+  NodeList<CompilationUnitMember> get declarations => _declarations;
+  /**
+   * Return the directives contained in this compilation unit.
+   * @return the directives contained in this compilation unit
+   */
+  NodeList<Directive> get directives => _directives;
+  /**
+   * Return the element associated with this compilation unit, or {@code null} if the AST structure
+   * has not been resolved.
+   * @return the element associated with this compilation unit
+   */
+  CompilationUnitElement get element => _element;
+  Token get endToken => _endToken;
+  /**
+   * Return an array containing all of the 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 errors {
+    throw new UnsupportedOperationException();
+  }
+  int get length {
+    Token endToken4 = endToken;
+    if (endToken4 == null) {
+      return 0;
+    }
+    return endToken4.offset + endToken4.length - beginToken.offset;
+  }
+  int get offset {
+    Token beginToken4 = beginToken;
+    if (beginToken4 == null) {
+      return 0;
+    }
+    return beginToken4.offset;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_scriptTag, visitor);
+    if (directivesAreBeforeDeclarations()) {
+      _directives.accept(visitor);
+      _declarations.accept(visitor);
+    } else {
+      for (ASTNode child in sortedDirectivesAndDeclarations) {
+        child.accept(visitor);
+      }
+    }
+  }
+  /**
+   * Return {@code true} if all of the directives are lexically before any declarations.
+   * @return {@code true} if all of the directives are lexically before any declarations
+   */
+  bool directivesAreBeforeDeclarations() {
+    if (_directives.isEmpty || _declarations.isEmpty) {
+      return true;
+    }
+    Directive lastDirective = _directives[_directives.length - 1];
+    CompilationUnitMember firstDeclaration = _declarations[0];
+    return lastDirective.offset < firstDeclaration.offset;
+  }
+  /**
+   * Return an array containing all of the directives and declarations in this compilation unit,
+   * sorted in lexical order.
+   * @return the directives and declarations in this compilation unit in the order in which they
+   * appeared in the original source
+   */
+  List<ASTNode> get sortedDirectivesAndDeclarations {
+    List<ASTNode> childList = new List<ASTNode>();
+    childList.addAll(_directives);
+    childList.addAll(_declarations);
+    List<ASTNode> children = new List.from(childList);
+    children.sort();
+    return children;
+  }
+}
+/**
+ * Instances of the class {@code CompilationUnitMember} defines the behavior common to nodes that
+ * declare a name within the scope of a compilation unit.
+ * <pre>
+ * compilationUnitMember ::={@link ClassDeclaration classDeclaration}| {@link TypeAlias typeAlias}| {@link FunctionDeclaration functionDeclaration}| {@link MethodDeclaration getOrSetDeclaration}| {@link VariableDeclaration constantsDeclaration}| {@link VariableDeclaration variablesDeclaration}</pre>
+ */
+abstract class CompilationUnitMember extends Declaration {
+  /**
+   * 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) : super(comment, metadata) {
+  }
+}
+/**
+ * Instances of the class {@code ConditionalExpression} represent a conditional expression.
+ * <pre>
+ * conditionalExpression ::={@link Expression condition} '?' {@link Expression thenExpression} ':' {@link Expression elseExpression}</pre>
+ */
+class ConditionalExpression extends Expression {
+  /**
+   * The condition used to determine which of the expressions is executed next.
+   */
+  Expression _condition;
+  /**
+   * The token used to separate the condition from the then expression.
+   */
+  Token _question;
+  /**
+   * The expression that is executed if the condition evaluates to {@code true}.
+   */
+  Expression _thenExpression;
+  /**
+   * The token used to separate the then expression from the else expression.
+   */
+  Token _colon;
+  /**
+   * The expression that is executed if the condition evaluates to {@code false}.
+   */
+  Expression _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._condition = becomeParentOf(condition);
+    this._question = question;
+    this._thenExpression = becomeParentOf(thenExpression);
+    this._colon = colon;
+    this._elseExpression = becomeParentOf(elseExpression);
+  }
+  accept(ASTVisitor visitor) => visitor.visitConditionalExpression(this);
+  Token get beginToken => _condition.beginToken;
+  /**
+   * Return the token used to separate the then expression from the else expression.
+   * @return the token used to separate the then expression from the else expression
+   */
+  Token get colon => _colon;
+  /**
+   * Return the condition used to determine which of the expressions is executed next.
+   * @return the condition used to determine which expression is executed next
+   */
+  Expression get condition => _condition;
+  /**
+   * Return the expression that is executed if the condition evaluates to {@code false}.
+   * @return the expression that is executed if the condition evaluates to {@code false}
+   */
+  Expression get elseExpression => _elseExpression;
+  Token get endToken => _elseExpression.endToken;
+  /**
+   * Return the token used to separate the condition from the then expression.
+   * @return the token used to separate the condition from the then expression
+   */
+  Token get question => _question;
+  /**
+   * Return the expression that is executed if the condition evaluates to {@code true}.
+   * @return the expression that is executed if the condition evaluates to {@code true}
+   */
+  Expression get thenExpression => _thenExpression;
+  /**
+   * 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;
+  }
+  /**
+   * 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) {
+    _condition = becomeParentOf(expression);
+  }
+  /**
+   * Set the expression that is executed if the condition evaluates to {@code false} to the given
+   * expression.
+   * @param expression the expression that is executed if the condition evaluates to {@code false}
+   */
+  void set elseExpression2(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;
+  }
+  /**
+   * 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) {
+    _thenExpression = becomeParentOf(expression);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_condition, visitor);
+    safelyVisitChild(_thenExpression, visitor);
+    safelyVisitChild(_elseExpression, visitor);
+  }
+}
+/**
+ * Instances of the class {@code ConstructorDeclaration} represent a constructor declaration.
+ * <pre>
+ * constructorDeclaration ::=
+ * constructorSignature {@link FunctionBody body}?
+ * | constructorName formalParameterList ':' 'this' ('.' {@link SimpleIdentifier name})? arguments
+ * constructorSignature ::=
+ * 'external'? constructorName formalParameterList initializerList?
+ * | 'external'? 'factory' factoryName formalParameterList initializerList?
+ * | 'external'? 'const'  constructorName formalParameterList initializerList?
+ * constructorName ::={@link SimpleIdentifier returnType} ('.' {@link SimpleIdentifier name})?
+ * factoryName ::={@link Identifier returnType} ('.' {@link SimpleIdentifier name})?
+ * initializerList ::=
+ * ':' {@link ConstructorInitializer initializer} (',' {@link ConstructorInitializer initializer})
+ * </pre>
+ */
+class ConstructorDeclaration extends ClassMember {
+  /**
+   * The token for the 'external' keyword, or {@code null} if the constructor is not external.
+   */
+  Token _externalKeyword;
+  /**
+   * The token for the 'const' keyword.
+   */
+  Token _constKeyword;
+  /**
+   * The token for the 'factory' keyword.
+   */
+  Token _factoryKeyword;
+  /**
+   * The type of object being created. This can be different than the type in which the constructor
+   * is being declared if the constructor is the implementation of a factory constructor.
+   */
+  Identifier _returnType;
+  /**
+   * The token for the period before the constructor name, or {@code null} if the constructor being
+   * declared is unnamed.
+   */
+  Token _period;
+  /**
+   * The name of the constructor, or {@code null} if the constructor being declared is unnamed.
+   */
+  SimpleIdentifier _name;
+  /**
+   * The element associated with this constructor, or {@code null} if the AST structure has not been
+   * resolved or if this constructor could not be resolved.
+   */
+  ConstructorElement _element;
+  /**
+   * The parameters associated with the constructor.
+   */
+  FormalParameterList _parameters;
+  /**
+   * The token for the separator (colon or equals) before the initializers, or {@code null} if there
+   * are no initializers.
+   */
+  Token _separator;
+  /**
+   * The initializers associated with the constructor.
+   */
+  NodeList<ConstructorInitializer> _initializers;
+  /**
+   * The name of the constructor to which this constructor will be redirected, or {@code null} if
+   * this is not a redirecting factory constructor.
+   */
+  ConstructorName _redirectedConstructor;
+  /**
+   * The body of the constructor, or {@code null} if the constructor does not have a body.
+   */
+  FunctionBody _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) : super(comment, metadata) {
+    this._initializers = new NodeList<ConstructorInitializer>(this);
+    this._externalKeyword = externalKeyword;
+    this._constKeyword = constKeyword;
+    this._factoryKeyword = factoryKeyword;
+    this._returnType = becomeParentOf(returnType);
+    this._period = period;
+    this._name = becomeParentOf(name);
+    this._parameters = becomeParentOf(parameters);
+    this._separator = separator;
+    this._initializers.addAll(initializers);
+    this._redirectedConstructor = becomeParentOf(redirectedConstructor);
+    this._body = becomeParentOf(body);
+  }
+  accept(ASTVisitor visitor) => visitor.visitConstructorDeclaration(this);
+  /**
+   * Return the body of the constructor, or {@code null} if the constructor does not have a body.
+   * @return the body of the constructor
+   */
+  FunctionBody get body => _body;
+  /**
+   * Return the token for the 'const' keyword.
+   * @return the token for the 'const' keyword
+   */
+  Token get constKeyword => _constKeyword;
+  /**
+   * Return the element associated with this constructor , or {@code null} if the AST structure has
+   * not been resolved or if this constructor could not be resolved.
+   * @return the element associated with this constructor
+   */
+  ConstructorElement get element => _element;
+  Token get endToken {
+    if (_body != null) {
+      return _body.endToken;
+    } else if (!_initializers.isEmpty) {
+      return _initializers.endToken;
+    }
+    return _parameters.endToken;
+  }
+  /**
+   * Return the token for the 'external' keyword, or {@code null} if the constructor is not
+   * external.
+   * @return the token for the 'external' keyword
+   */
+  Token get externalKeyword => _externalKeyword;
+  /**
+   * Return the token for the 'factory' keyword.
+   * @return the token for the 'factory' keyword
+   */
+  Token get factoryKeyword => _factoryKeyword;
+  /**
+   * Return the initializers associated with the constructor.
+   * @return the initializers associated with the constructor
+   */
+  NodeList<ConstructorInitializer> get initializers => _initializers;
+  /**
+   * Return the name of the constructor, or {@code null} if the constructor being declared is
+   * unnamed.
+   * @return the name of the constructor
+   */
+  SimpleIdentifier get name => _name;
+  /**
+   * Return the parameters associated with the constructor.
+   * @return the parameters associated with the constructor
+   */
+  FormalParameterList get parameters => _parameters;
+  /**
+   * Return the token for the period before the constructor name, or {@code null} if the constructor
+   * being declared is unnamed.
+   * @return the token for the period before the constructor name
+   */
+  Token get period => _period;
+  /**
+   * Return the name of the constructor to which this constructor will be redirected, or{@code null} if this is not a redirecting factory constructor.
+   * @return the name of the constructor to which this constructor will be redirected
+   */
+  ConstructorName get redirectedConstructor => _redirectedConstructor;
+  /**
+   * Return the type of object being created. This can be different than the type in which the
+   * constructor is being declared if the constructor is the implementation of a factory
+   * constructor.
+   * @return the type of object being created
+   */
+  Identifier get returnType => _returnType;
+  /**
+   * Return the token for the separator (colon or equals) before the initializers, or {@code null}if there are no initializers.
+   * @return the token for the separator (colon or equals) before the initializers
+   */
+  Token get separator => _separator;
+  /**
+   * Set the body of the constructor to the given function body.
+   * @param functionBody the body of the constructor
+   */
+  void set body3(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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * Set the name of the constructor to the given identifier.
+   * @param identifier the name of the constructor
+   */
+  void set name5(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);
+  }
+  /**
+   * 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;
+  }
+  /**
+   * Set the name of the constructor to which this constructor will be redirected to the given
+   * constructor name.
+   * @param redirectedConstructor the name of the constructor to which this constructor will be
+   * redirected
+   */
+  void set redirectedConstructor2(ConstructorName redirectedConstructor) {
+    this._redirectedConstructor = becomeParentOf(redirectedConstructor);
+  }
+  /**
+   * 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) {
+    _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 visitChildren(ASTVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_returnType, visitor);
+    safelyVisitChild(_name, visitor);
+    safelyVisitChild(_parameters, visitor);
+    _initializers.accept(visitor);
+    safelyVisitChild(_body, visitor);
+  }
+  Token get firstTokenAfterCommentAndMetadata {
+    Token leftMost2 = leftMost([_externalKeyword, _constKeyword, _factoryKeyword]);
+    if (leftMost2 != null) {
+      return leftMost2;
+    }
+    return _returnType.beginToken;
+  }
+  /**
+   * Return the left-most of the given tokens, or {@code null} if there are no tokens given or if
+   * all of the given tokens are {@code null}.
+   * @param tokens the tokens being compared to find the left-most token
+   * @return the left-most of the given tokens
+   */
+  Token leftMost(List<Token> tokens) {
+    Token leftMost = null;
+    int offset = 2147483647;
+    for (Token token in tokens) {
+      if (token != null && token.offset < offset) {
+        leftMost = token;
+      }
+    }
+    return leftMost;
+  }
+}
+/**
+ * Instances of the class {@code ConstructorFieldInitializer} represent the initialization of a
+ * field within a constructor's initialization list.
+ * <pre>
+ * fieldInitializer ::=
+ * ('this' '.')? {@link SimpleIdentifier fieldName} '=' {@link Expression conditionalExpression cascadeSection*}</pre>
+ */
+class ConstructorFieldInitializer extends ConstructorInitializer {
+  /**
+   * The token for the 'this' keyword, or {@code null} if there is no 'this' keyword.
+   */
+  Token _keyword;
+  /**
+   * The token for the period after the 'this' keyword, or {@code null} if there is no 'this'
+   * keyword.
+   */
+  Token _period;
+  /**
+   * The name of the field being initialized.
+   */
+  SimpleIdentifier _fieldName;
+  /**
+   * The token for the equal sign between the field name and the expression.
+   */
+  Token _equals;
+  /**
+   * The expression computing the value to which the field will be initialized.
+   */
+  Expression _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._keyword = keyword;
+    this._period = period;
+    this._fieldName = becomeParentOf(fieldName);
+    this._equals = equals;
+    this._expression = becomeParentOf(expression);
+  }
+  accept(ASTVisitor visitor) => visitor.visitConstructorFieldInitializer(this);
+  Token get beginToken {
+    if (_keyword != null) {
+      return _keyword;
+    }
+    return _fieldName.beginToken;
+  }
+  Token get endToken => _expression.endToken;
+  /**
+   * Return the token for the equal sign between the field name and the expression.
+   * @return the token for the equal sign between the field name and the expression
+   */
+  Token get equals => _equals;
+  /**
+   * Return the expression computing the value to which the field will be initialized.
+   * @return the expression computing the value to which the field will be initialized
+   */
+  Expression get expression => _expression;
+  /**
+   * Return the name of the field being initialized.
+   * @return the name of the field being initialized
+   */
+  SimpleIdentifier get fieldName => _fieldName;
+  /**
+   * Return the token for the 'this' keyword, or {@code null} if there is no 'this' keyword.
+   * @return the token for the 'this' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * Return the token for the period after the 'this' keyword, or {@code null} if there is no 'this'
+   * keyword.
+   * @return the token for the period after the 'this' keyword
+   */
+  Token get period => _period;
+  /**
+   * 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;
+  }
+  /**
+   * 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);
+  }
+  /**
+   * 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) {
+    _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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_fieldName, visitor);
+    safelyVisitChild(_expression, visitor);
+  }
+}
+/**
+ * Instances of the class {@code ConstructorInitializer} defines the behavior of nodes that can
+ * occur in the initializer list of a constructor declaration.
+ * <pre>
+ * constructorInitializer ::={@link SuperConstructorInvocation superInvocation}| {@link ConstructorFieldInitializer fieldInitializer}</pre>
+ */
+abstract class ConstructorInitializer extends ASTNode {
+}
+/**
+ * Instances of the class {@code ConstructorName} represent the name of the constructor.
+ * <pre>
+ * constructorName:
+ * type ('.' identifier)?
+ * </pre>
+ */
+class ConstructorName extends ASTNode {
+  /**
+   * The name of the type defining the constructor.
+   */
+  TypeName _type;
+  /**
+   * The token for the period before the constructor name, or {@code null} if the specified
+   * constructor is the unnamed constructor.
+   */
+  Token _period;
+  /**
+   * The name of the constructor, or {@code null} if the specified constructor is the unnamed
+   * constructor.
+   */
+  SimpleIdentifier _name;
+  /**
+   * The element associated with this constructor name, or {@code null} if the AST structure has not
+   * been resolved or if this constructor name could not be resolved.
+   */
+  ConstructorElement _element;
+  /**
+   * 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._type = becomeParentOf(type);
+    this._period = period;
+    this._name = becomeParentOf(name);
+  }
+  accept(ASTVisitor visitor) => visitor.visitConstructorName(this);
+  Token get beginToken => _type.beginToken;
+  /**
+   * Return the element associated with this constructor name, or {@code null} if the AST structure
+   * has not been resolved or if this constructor name could not be resolved.
+   * @return the element associated with this constructor name
+   */
+  ConstructorElement get element => _element;
+  Token get endToken {
+    if (_name != null) {
+      return _name.endToken;
+    }
+    return _type.endToken;
+  }
+  /**
+   * Return the name of the constructor, or {@code null} if the specified constructor is the unnamed
+   * constructor.
+   * @return the name of the constructor
+   */
+  SimpleIdentifier get name => _name;
+  /**
+   * Return the token for the period before the constructor name, or {@code null} if the specified
+   * constructor is the unnamed constructor.
+   * @return the token for the period before the constructor name
+   */
+  Token get period => _period;
+  /**
+   * Return the name of the type defining the constructor.
+   * @return the name of the type defining the constructor
+   */
+  TypeName get type => _type;
+  /**
+   * 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;
+  }
+  /**
+   * 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);
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_type, visitor);
+    safelyVisitChild(_name, visitor);
+  }
+}
+/**
+ * Instances of the class {@code ContinueStatement} represent a continue statement.
+ * <pre>
+ * continueStatement ::=
+ * 'continue' {@link SimpleIdentifier label}? ';'
+ * </pre>
+ */
+class ContinueStatement extends Statement {
+  /**
+   * The token representing the 'continue' keyword.
+   */
+  Token _keyword;
+  /**
+   * The label associated with the statement, or {@code null} if there is no label.
+   */
+  SimpleIdentifier _label;
+  /**
+   * The semicolon terminating the statement.
+   */
+  Token _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._keyword = keyword;
+    this._label = becomeParentOf(label);
+    this._semicolon = semicolon;
+  }
+  accept(ASTVisitor visitor) => visitor.visitContinueStatement(this);
+  Token get beginToken => _keyword;
+  Token get endToken => _semicolon;
+  /**
+   * Return the token representing the 'continue' keyword.
+   * @return the token representing the 'continue' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * Return the label associated with the statement, or {@code null} if there is no label.
+   * @return the label associated with the statement
+   */
+  SimpleIdentifier get label => _label;
+  /**
+   * Return the semicolon terminating the statement.
+   * @return the semicolon terminating the statement
+   */
+  Token get semicolon => _semicolon;
+  /**
+   * 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;
+  }
+  /**
+   * Set the label associated with the statement to the given label.
+   * @param identifier the label associated with the statement
+   */
+  void set label3(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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_label, visitor);
+  }
+}
+/**
+ * The abstract class {@code Declaration} defines the behavior common to nodes that represent the
+ * declaration of a name. Each declared name is visible within a name scope.
+ */
+abstract class Declaration extends AnnotatedNode {
+  /**
+   * 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) : super(comment, metadata) {
+  }
+}
+/**
+ * Instances of the class {@code DefaultFormalParameter} represent a formal parameter with a default
+ * value. There are two kinds of parameters that are both represented by this class: named formal
+ * parameters and positional formal parameters.
+ * <pre>
+ * defaultFormalParameter ::={@link NormalFormalParameter normalFormalParameter} ('=' {@link Expression defaultValue})?
+ * defaultNamedParameter ::={@link NormalFormalParameter normalFormalParameter} (':' {@link Expression defaultValue})?
+ * </pre>
+ */
+class DefaultFormalParameter extends FormalParameter {
+  /**
+   * The formal parameter with which the default value is associated.
+   */
+  NormalFormalParameter _parameter;
+  /**
+   * The kind of this parameter.
+   */
+  ParameterKind _kind;
+  /**
+   * The token separating the parameter from the default value, or {@code null} if there is no
+   * default value.
+   */
+  Token _separator;
+  /**
+   * The expression computing the default value for the parameter, or {@code null} if there is no
+   * default value.
+   */
+  Expression _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._parameter = becomeParentOf(parameter);
+    this._kind = kind;
+    this._separator = separator;
+    this._defaultValue = becomeParentOf(defaultValue);
+  }
+  accept(ASTVisitor visitor) => visitor.visitDefaultFormalParameter(this);
+  Token get beginToken => _parameter.beginToken;
+  /**
+   * Return the expression computing the default value for the parameter, or {@code null} if there
+   * is no default value.
+   * @return the expression computing the default value for the parameter
+   */
+  Expression get defaultValue => _defaultValue;
+  Token get endToken {
+    if (_defaultValue != null) {
+      return _defaultValue.endToken;
+    }
+    return _parameter.endToken;
+  }
+  SimpleIdentifier get identifier => _parameter.identifier;
+  ParameterKind get kind => _kind;
+  /**
+   * Return the formal parameter with which the default value is associated.
+   * @return the formal parameter with which the default value is associated
+   */
+  NormalFormalParameter get parameter => _parameter;
+  /**
+   * Return the token separating the parameter from the default value, or {@code null} if there is
+   * no default value.
+   * @return the token separating the parameter from the default value
+   */
+  Token get separator => _separator;
+  /**
+   * Return {@code true} if this parameter is a const parameter.
+   * @return {@code true} if this parameter is a const parameter
+   */
+  bool isConst() => _parameter != null && _parameter.isConst();
+  /**
+   * Return {@code true} if this parameter is a final parameter.
+   * @return {@code true} if this parameter is a final parameter
+   */
+  bool isFinal() => _parameter != null && _parameter.isFinal();
+  /**
+   * 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) {
+    _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;
+  }
+  /**
+   * 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) {
+    _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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_parameter, visitor);
+    safelyVisitChild(_defaultValue, visitor);
+  }
+}
+/**
+ * The abstract class {@code Directive} defines the behavior common to nodes that represent a
+ * directive.
+ * <pre>
+ * directive ::={@link ExportDirective exportDirective}| {@link ImportDirective importDirective}| {@link LibraryDirective libraryDirective}| {@link PartDirective partDirective}| {@link PartOfDirective partOfDirective}</pre>
+ */
+abstract class Directive extends AnnotatedNode {
+  /**
+   * 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.
+   */
+  Element _element;
+  /**
+   * 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) : super(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.
+   * @return the element associated with this directive
+   */
+  Element get element => _element;
+  /**
+   * Return the token representing the keyword that introduces this directive ('import', 'export',
+   * 'library' or 'part').
+   * @return the token representing the keyword that introduces this directive
+   */
+  Token get keyword;
+  /**
+   * 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;
+  }
+}
+/**
+ * Instances of the class {@code DoStatement} represent a do statement.
+ * <pre>
+ * doStatement ::=
+ * 'do' {@link Statement body} 'while' '(' {@link Expression condition} ')' ';'
+ * </pre>
+ */
+class DoStatement extends Statement {
+  /**
+   * The token representing the 'do' keyword.
+   */
+  Token _doKeyword;
+  /**
+   * The body of the loop.
+   */
+  Statement _body;
+  /**
+   * The token representing the 'while' keyword.
+   */
+  Token _whileKeyword;
+  /**
+   * The left parenthesis.
+   */
+  Token _leftParenthesis;
+  /**
+   * The condition that determines when the loop will terminate.
+   */
+  Expression _condition;
+  /**
+   * The right parenthesis.
+   */
+  Token _rightParenthesis;
+  /**
+   * The semicolon terminating the statement.
+   */
+  Token _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._doKeyword = doKeyword;
+    this._body = becomeParentOf(body);
+    this._whileKeyword = whileKeyword;
+    this._leftParenthesis = leftParenthesis;
+    this._condition = becomeParentOf(condition);
+    this._rightParenthesis = rightParenthesis;
+    this._semicolon = semicolon;
+  }
+  accept(ASTVisitor visitor) => visitor.visitDoStatement(this);
+  Token get beginToken => _doKeyword;
+  /**
+   * Return the body of the loop.
+   * @return the body of the loop
+   */
+  Statement get body => _body;
+  /**
+   * Return the condition that determines when the loop will terminate.
+   * @return the condition that determines when the loop will terminate
+   */
+  Expression get condition => _condition;
+  /**
+   * Return the token representing the 'do' keyword.
+   * @return the token representing the 'do' keyword
+   */
+  Token get doKeyword => _doKeyword;
+  Token get endToken => _semicolon;
+  /**
+   * Return the left parenthesis.
+   * @return the left parenthesis
+   */
+  Token get leftParenthesis => _leftParenthesis;
+  /**
+   * Return the right parenthesis.
+   * @return the right parenthesis
+   */
+  Token get rightParenthesis => _rightParenthesis;
+  /**
+   * Return the semicolon terminating the statement.
+   * @return the semicolon terminating the statement
+   */
+  Token get semicolon => _semicolon;
+  /**
+   * Return the token representing the 'while' keyword.
+   * @return the token representing the 'while' keyword
+   */
+  Token get whileKeyword => _whileKeyword;
+  /**
+   * Set the body of the loop to the given statement.
+   * @param statement the body of the loop
+   */
+  void set body4(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) {
+    _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;
+  }
+  /**
+   * Set the left parenthesis to the given token.
+   * @param parenthesis the left parenthesis
+   */
+  void set leftParenthesis5(Token parenthesis) {
+    _leftParenthesis = parenthesis;
+  }
+  /**
+   * Set the right parenthesis to the given token.
+   * @param parenthesis the right parenthesis
+   */
+  void set rightParenthesis5(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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_body, visitor);
+    safelyVisitChild(_condition, visitor);
+  }
+}
+/**
+ * Instances of the class {@code DoubleLiteral} represent a floating point literal expression.
+ * <pre>
+ * doubleLiteral ::=
+ * decimalDigit+ ('.' decimalDigit*)? exponent?
+ * | '.' decimalDigit+ exponent?
+ * exponent ::=
+ * ('e' | 'E') ('+' | '-')? decimalDigit+
+ * </pre>
+ */
+class DoubleLiteral extends Literal {
+  /**
+   * The token representing the literal.
+   */
+  Token _literal;
+  /**
+   * The value of the literal.
+   */
+  double _value = 0.0;
+  /**
+   * 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._literal = literal;
+    this._value = value;
+  }
+  accept(ASTVisitor visitor) => visitor.visitDoubleLiteral(this);
+  Token get beginToken => _literal;
+  Token get endToken => _literal;
+  /**
+   * Return the token representing the literal.
+   * @return the token representing the literal
+   */
+  Token get literal => _literal;
+  /**
+   * Return the value of the literal.
+   * @return the value of the literal
+   */
+  double get value => _value;
+  /**
+   * 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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+  }
+}
+/**
+ * Instances of the class {@code EmptyFunctionBody} represent an empty function body, which can only
+ * appear in constructors or abstract methods.
+ * <pre>
+ * emptyFunctionBody ::=
+ * ';'
+ * </pre>
+ */
+class EmptyFunctionBody extends FunctionBody {
+  /**
+   * The token representing the semicolon that marks the end of the function body.
+   */
+  Token _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._semicolon = semicolon;
+  }
+  accept(ASTVisitor visitor) => visitor.visitEmptyFunctionBody(this);
+  Token get beginToken => _semicolon;
+  Token get endToken => _semicolon;
+  /**
+   * Return the token representing the semicolon that marks the end of the function body.
+   * @return the token representing the semicolon that marks the end of the function body
+   */
+  Token get semicolon => _semicolon;
+  /**
+   * Set the token representing the semicolon that marks the end of the function body to the given
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+  }
+}
+/**
+ * Instances of the class {@code EmptyStatement} represent an empty statement.
+ * <pre>
+ * emptyStatement ::=
+ * ';'
+ * </pre>
+ */
+class EmptyStatement extends Statement {
+  /**
+   * The semicolon terminating the statement.
+   */
+  Token _semicolon;
+  /**
+   * Initialize a newly created empty statement.
+   * @param semicolon the semicolon terminating the statement
+   */
+  EmptyStatement(Token semicolon) {
+    this._semicolon = semicolon;
+  }
+  accept(ASTVisitor visitor) => visitor.visitEmptyStatement(this);
+  Token get beginToken => _semicolon;
+  Token get endToken => _semicolon;
+  /**
+   * Return the semicolon terminating the statement.
+   * @return the semicolon terminating the statement
+   */
+  Token get semicolon => _semicolon;
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+  }
+}
+/**
+ * Instances of the class {@code ExportDirective} represent an export directive.
+ * <pre>
+ * exportDirective ::={@link Annotation metadata} 'export' {@link StringLiteral libraryUri} {@link Combinator combinator}* ';'
+ * </pre>
+ */
+class ExportDirective extends NamespaceDirective {
+  /**
+   * 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) : super(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);
+  }
+}
+/**
+ * Instances of the class {@code Expression} defines the behavior common to nodes that represent an
+ * expression.
+ * <pre>
+ * expression ::={@link AssignmentExpression assignmentExpression}| {@link ConditionalExpression conditionalExpression} cascadeSection
+ * | {@link ThrowExpression throwExpression}</pre>
+ */
+abstract class Expression extends ASTNode {
+  /**
+   * The static type of this expression, or {@code null} if the AST structure has not been resolved.
+   */
+  Type2 _staticType;
+  /**
+   * The propagated type of this expression, or {@code null} if type propagation has not been
+   * performed on the AST structure.
+   */
+  Type2 _propagatedType;
+  /**
+   * Return the propagated type of this expression, or {@code null} if type propagation has not been
+   * performed on the AST structure.
+   * @return the propagated type of this expression
+   */
+  Type2 get propagatedType => _propagatedType;
+  /**
+   * Return the static type of this expression, or {@code null} if the AST structure has not been
+   * resolved.
+   * @return the static type of this expression
+   */
+  Type2 get staticType => _staticType;
+  /**
+   * Return {@code true} if this expression is syntactically valid for the LHS of an{@link AssignmentExpression assignment expression}.
+   * @return {@code true} if this expression matches the {@code assignableExpression} production
+   */
+  bool isAssignable() => false;
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+}
+/**
+ * Instances of the class {@code ExpressionFunctionBody} represent a function body consisting of a
+ * single expression.
+ * <pre>
+ * expressionFunctionBody ::=
+ * '=>' {@link Expression expression} ';'
+ * </pre>
+ */
+class ExpressionFunctionBody extends FunctionBody {
+  /**
+   * The token introducing the expression that represents the body of the function.
+   */
+  Token _functionDefinition;
+  /**
+   * The expression representing the body of the function.
+   */
+  Expression _expression;
+  /**
+   * The semicolon terminating the statement.
+   */
+  Token _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._functionDefinition = functionDefinition;
+    this._expression = becomeParentOf(expression);
+    this._semicolon = semicolon;
+  }
+  accept(ASTVisitor visitor) => visitor.visitExpressionFunctionBody(this);
+  Token get beginToken => _functionDefinition;
+  Token get endToken {
+    if (_semicolon != null) {
+      return _semicolon;
+    }
+    return _expression.endToken;
+  }
+  /**
+   * Return the expression representing the body of the function.
+   * @return the expression representing the body of the function
+   */
+  Expression get expression => _expression;
+  /**
+   * Return the token introducing the expression that represents the body of the function.
+   * @return the function definition token
+   */
+  Token get functionDefinition => _functionDefinition;
+  /**
+   * Return the semicolon terminating the statement.
+   * @return the semicolon terminating the statement
+   */
+  Token get semicolon => _semicolon;
+  /**
+   * 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);
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_expression, visitor);
+  }
+}
+/**
+ * Instances of the class {@code ExpressionStatement} wrap an expression as a statement.
+ * <pre>
+ * expressionStatement ::={@link Expression expression}? ';'
+ * </pre>
+ */
+class ExpressionStatement extends Statement {
+  /**
+   * The expression that comprises the statement.
+   */
+  Expression _expression;
+  /**
+   * The semicolon terminating the statement, or {@code null} if the expression is a function
+   * expression and isn't followed by a semicolon.
+   */
+  Token _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._expression = becomeParentOf(expression);
+    this._semicolon = semicolon;
+  }
+  accept(ASTVisitor visitor) => visitor.visitExpressionStatement(this);
+  Token get beginToken => _expression.beginToken;
+  Token get endToken {
+    if (_semicolon != null) {
+      return _semicolon;
+    }
+    return _expression.endToken;
+  }
+  /**
+   * Return the expression that comprises the statement.
+   * @return the expression that comprises the statement
+   */
+  Expression get expression => _expression;
+  /**
+   * Return the semicolon terminating the statement.
+   * @return the semicolon terminating the statement
+   */
+  Token get semicolon => _semicolon;
+  bool isSynthetic() => _expression.isSynthetic() && _semicolon.isSynthetic();
+  /**
+   * 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);
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_expression, visitor);
+  }
+}
+/**
+ * Instances of the class {@code ExtendsClause} represent the "extends" clause in a class
+ * declaration.
+ * <pre>
+ * extendsClause ::=
+ * 'extends' {@link TypeName superclass}</pre>
+ */
+class ExtendsClause extends ASTNode {
+  /**
+   * The token representing the 'extends' keyword.
+   */
+  Token _keyword;
+  /**
+   * The name of the class that is being extended.
+   */
+  TypeName _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._keyword = keyword;
+    this._superclass = becomeParentOf(superclass);
+  }
+  accept(ASTVisitor visitor) => visitor.visitExtendsClause(this);
+  Token get beginToken => _keyword;
+  Token get endToken => _superclass.endToken;
+  /**
+   * Return the token representing the 'extends' keyword.
+   * @return the token representing the 'extends' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * Return the name of the class that is being extended.
+   * @return the name of the class that is being extended
+   */
+  TypeName get superclass => _superclass;
+  /**
+   * 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;
+  }
+  /**
+   * 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) {
+    _superclass = becomeParentOf(name);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_superclass, visitor);
+  }
+}
+/**
+ * Instances of the class {@code FieldDeclaration} represent the declaration of one or more fields
+ * of the same type.
+ * <pre>
+ * fieldDeclaration ::=
+ * 'static'? {@link VariableDeclarationList fieldList} ';'
+ * </pre>
+ */
+class FieldDeclaration extends ClassMember {
+  /**
+   * The token representing the 'static' keyword, or {@code null} if the fields are not static.
+   */
+  Token _keyword;
+  /**
+   * The fields being declared.
+   */
+  VariableDeclarationList _fieldList;
+  /**
+   * The semicolon terminating the declaration.
+   */
+  Token _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) : super(comment, metadata) {
+    this._keyword = keyword;
+    this._fieldList = becomeParentOf(fieldList);
+    this._semicolon = semicolon;
+  }
+  accept(ASTVisitor visitor) => visitor.visitFieldDeclaration(this);
+  Token get endToken => _semicolon;
+  /**
+   * Return the fields being declared.
+   * @return the fields being declared
+   */
+  VariableDeclarationList get fields => _fieldList;
+  /**
+   * Return the token representing the 'static' keyword, or {@code null} if the fields are not
+   * static.
+   * @return the token representing the 'static' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * Return the semicolon terminating the declaration.
+   * @return the semicolon terminating the declaration
+   */
+  Token get semicolon => _semicolon;
+  /**
+   * Set the fields being declared to the given list of variables.
+   * @param fieldList the fields being declared
+   */
+  void set fields2(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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_fieldList, visitor);
+  }
+  Token get firstTokenAfterCommentAndMetadata {
+    if (_keyword != null) {
+      return _keyword;
+    }
+    return _fieldList.beginToken;
+  }
+}
+/**
+ * Instances of the class {@code FieldFormalParameter} represent a field formal parameter.
+ * <pre>
+ * fieldFormalParameter ::=
+ * ('final' {@link TypeName type} | 'const' {@link TypeName type} | 'var' | {@link TypeName type})? 'this' '.' {@link SimpleIdentifier identifier}</pre>
+ */
+class FieldFormalParameter extends NormalFormalParameter {
+  /**
+   * The token representing either the 'final', 'const' or 'var' keyword, or {@code null} if no
+   * keyword was used.
+   */
+  Token _keyword;
+  /**
+   * The name of the declared type of the parameter, or {@code null} if the parameter does not have
+   * a declared type.
+   */
+  TypeName _type;
+  /**
+   * The token representing the 'this' keyword.
+   */
+  Token _thisToken;
+  /**
+   * The token representing the period.
+   */
+  Token _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) : super(comment, metadata, identifier) {
+    this._keyword = keyword;
+    this._type = becomeParentOf(type);
+    this._thisToken = thisToken;
+    this._period = period;
+  }
+  accept(ASTVisitor visitor) => visitor.visitFieldFormalParameter(this);
+  Token get beginToken {
+    if (_keyword != null) {
+      return _keyword;
+    } else if (_type != null) {
+      return _type.beginToken;
+    }
+    return _thisToken;
+  }
+  Token get endToken => identifier.endToken;
+  /**
+   * Return the token representing either the 'final', 'const' or 'var' keyword.
+   * @return the token representing either the 'final', 'const' or 'var' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * Return the token representing the period.
+   * @return the token representing the period
+   */
+  Token get period => _period;
+  /**
+   * Return the token representing the 'this' keyword.
+   * @return the token representing the 'this' keyword
+   */
+  Token get thisToken => _thisToken;
+  /**
+   * Return the name of the declared type of the parameter, or {@code null} if the parameter does
+   * not have a declared type.
+   * @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;
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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) {
+    _type = becomeParentOf(typeName);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_type, visitor);
+    safelyVisitChild(identifier, visitor);
+  }
+}
+/**
+ * Instances of the class {@code ForEachStatement} represent a for-each statement.
+ * <pre>
+ * forEachStatement ::=
+ * 'for' '(' {@link SimpleFormalParameter loopParameter} 'in' {@link Expression iterator} ')' {@link Block body}</pre>
+ */
+class ForEachStatement extends Statement {
+  /**
+   * The token representing the 'for' keyword.
+   */
+  Token _forKeyword;
+  /**
+   * The left parenthesis.
+   */
+  Token _leftParenthesis;
+  /**
+   * The declaration of the loop variable.
+   */
+  SimpleFormalParameter _loopParameter;
+  /**
+   * The token representing the 'in' keyword.
+   */
+  Token _inKeyword;
+  /**
+   * The expression evaluated to produce the iterator.
+   */
+  Expression _iterator;
+  /**
+   * The right parenthesis.
+   */
+  Token _rightParenthesis;
+  /**
+   * The body of the loop.
+   */
+  Statement _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._forKeyword = forKeyword;
+    this._leftParenthesis = leftParenthesis;
+    this._loopParameter = becomeParentOf(loopParameter);
+    this._inKeyword = inKeyword;
+    this._iterator = becomeParentOf(iterator);
+    this._rightParenthesis = rightParenthesis;
+    this._body = becomeParentOf(body);
+  }
+  accept(ASTVisitor visitor) => visitor.visitForEachStatement(this);
+  Token get beginToken => _forKeyword;
+  /**
+   * Return the body of the loop.
+   * @return the body of the loop
+   */
+  Statement get body => _body;
+  Token get endToken => _body.endToken;
+  /**
+   * Return the token representing the 'for' keyword.
+   * @return the token representing the 'for' keyword
+   */
+  Token get forKeyword => _forKeyword;
+  /**
+   * Return the token representing the 'in' keyword.
+   * @return the token representing the 'in' keyword
+   */
+  Token get inKeyword => _inKeyword;
+  /**
+   * Return the expression evaluated to produce the iterator.
+   * @return the expression evaluated to produce the iterator
+   */
+  Expression get iterator => _iterator;
+  /**
+   * Return the left parenthesis.
+   * @return the left parenthesis
+   */
+  Token get leftParenthesis => _leftParenthesis;
+  /**
+   * Return the declaration of the loop variable.
+   * @return the declaration of the loop variable
+   */
+  SimpleFormalParameter get loopParameter => _loopParameter;
+  /**
+   * Return the right parenthesis.
+   * @return the right parenthesis
+   */
+  Token get rightParenthesis => _rightParenthesis;
+  /**
+   * 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);
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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) {
+    _iterator = becomeParentOf(expression);
+  }
+  /**
+   * Set the left parenthesis to the given token.
+   * @param leftParenthesis the left parenthesis
+   */
+  void set leftParenthesis6(Token leftParenthesis) {
+    this._leftParenthesis = leftParenthesis;
+  }
+  /**
+   * Set the declaration of the loop variable to the given parameter.
+   * @param parameter the declaration of the loop variable
+   */
+  void set loopParameter2(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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_loopParameter, visitor);
+    safelyVisitChild(_iterator, visitor);
+    safelyVisitChild(_body, visitor);
+  }
+}
+/**
+ * Instances of the class {@code ForStatement} represent a for statement.
+ * <pre>
+ * forStatement ::=
+ * 'for' '(' forLoopParts ')' {@link Statement statement}forLoopParts ::=
+ * forInitializerStatement ';' {@link Expression expression}? ';' {@link Expression expressionList}?
+ * forInitializerStatement ::={@link DefaultFormalParameter initializedVariableDeclaration}| {@link Expression expression}?
+ * </pre>
+ */
+class ForStatement extends Statement {
+  /**
+   * The token representing the 'for' keyword.
+   */
+  Token _forKeyword;
+  /**
+   * The left parenthesis.
+   */
+  Token _leftParenthesis;
+  /**
+   * The declaration of the loop variables, or {@code null} if there are no variables. Note that a
+   * for statement cannot have both a variable list and an initialization expression, but can
+   * validly have neither.
+   */
+  VariableDeclarationList _variableList;
+  /**
+   * The initialization expression, or {@code null} if there is no initialization expression. Note
+   * that a for statement cannot have both a variable list and an initialization expression, but can
+   * validly have neither.
+   */
+  Expression _initialization;
+  /**
+   * The semicolon separating the initializer and the condition.
+   */
+  Token _leftSeparator;
+  /**
+   * The condition used to determine when to terminate the loop.
+   */
+  Expression _condition;
+  /**
+   * The semicolon separating the condition and the updater.
+   */
+  Token _rightSeparator;
+  /**
+   * The list of expressions run after each execution of the loop body.
+   */
+  NodeList<Expression> _updaters;
+  /**
+   * The right parenthesis.
+   */
+  Token _rightParenthesis;
+  /**
+   * The body of the loop.
+   */
+  Statement _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._updaters = new NodeList<Expression>(this);
+    this._forKeyword = forKeyword;
+    this._leftParenthesis = leftParenthesis;
+    this._variableList = becomeParentOf(variableList);
+    this._initialization = becomeParentOf(initialization);
+    this._leftSeparator = leftSeparator;
+    this._condition = becomeParentOf(condition);
+    this._rightSeparator = rightSeparator;
+    this._updaters.addAll(updaters);
+    this._rightParenthesis = rightParenthesis;
+    this._body = becomeParentOf(body);
+  }
+  accept(ASTVisitor visitor) => visitor.visitForStatement(this);
+  Token get beginToken => _forKeyword;
+  /**
+   * Return the body of the loop.
+   * @return the body of the loop
+   */
+  Statement get body => _body;
+  /**
+   * Return the condition used to determine when to terminate the loop.
+   * @return the condition used to determine when to terminate the loop
+   */
+  Expression get condition => _condition;
+  Token get endToken => _body.endToken;
+  /**
+   * Return the token representing the 'for' keyword.
+   * @return the token representing the 'for' keyword
+   */
+  Token get forKeyword => _forKeyword;
+  /**
+   * Return the initialization expression, or {@code null} if there is no initialization expression.
+   * @return the initialization expression
+   */
+  Expression get initialization => _initialization;
+  /**
+   * Return the left parenthesis.
+   * @return the left parenthesis
+   */
+  Token get leftParenthesis => _leftParenthesis;
+  /**
+   * Return the semicolon separating the initializer and the condition.
+   * @return the semicolon separating the initializer and the condition
+   */
+  Token get leftSeparator => _leftSeparator;
+  /**
+   * Return the right parenthesis.
+   * @return the right parenthesis
+   */
+  Token get rightParenthesis => _rightParenthesis;
+  /**
+   * Return the semicolon separating the condition and the updater.
+   * @return the semicolon separating the condition and the updater
+   */
+  Token get rightSeparator => _rightSeparator;
+  /**
+   * Return the list of expressions run after each execution of the loop body.
+   * @return the list of expressions run after each execution of the loop body
+   */
+  NodeList<Expression> get updaters => _updaters;
+  /**
+   * Return the declaration of the loop variables, or {@code null} if there are no variables.
+   * @return the declaration of the loop variables, or {@code null} if there are no variables
+   */
+  VariableDeclarationList get variables => _variableList;
+  /**
+   * 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);
+  }
+  /**
+   * 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) {
+    _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;
+  }
+  /**
+   * Set the initialization expression to the given expression.
+   * @param initialization the initialization expression
+   */
+  void set initialization2(Expression initialization) {
+    this._initialization = becomeParentOf(initialization);
+  }
+  /**
+   * Set the left parenthesis to the given token.
+   * @param leftParenthesis the left parenthesis
+   */
+  void set leftParenthesis7(Token leftParenthesis) {
+    this._leftParenthesis = leftParenthesis;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * Set the right parenthesis to the given token.
+   * @param rightParenthesis the right parenthesis
+   */
+  void set rightParenthesis7(Token rightParenthesis) {
+    this._rightParenthesis = rightParenthesis;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * Set the declaration of the loop variables to the given parameter.
+   * @param variableList the declaration of the loop variables
+   */
+  void set variables2(VariableDeclarationList variableList) {
+    variableList = becomeParentOf(variableList);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_variableList, visitor);
+    safelyVisitChild(_initialization, visitor);
+    safelyVisitChild(_condition, visitor);
+    _updaters.accept(visitor);
+    safelyVisitChild(_body, visitor);
+  }
+}
+/**
+ * The abstract class {@code FormalParameter} defines the behavior of objects representing a
+ * parameter to a function.
+ * <pre>
+ * formalParameter ::={@link NormalFormalParameter normalFormalParameter}| {@link DefaultFormalParameter namedFormalParameter}| {@link DefaultFormalParameter optionalFormalParameter}</pre>
+ */
+abstract class FormalParameter extends ASTNode {
+  /**
+   * Return the element representing this parameter, or {@code null} if this parameter has not been
+   * resolved.
+   * @return the element representing this parameter
+   */
+  ParameterElement get element {
+    SimpleIdentifier identifier6 = identifier;
+    if (identifier6 == null) {
+      return null;
+    }
+    return identifier6.element as ParameterElement;
+  }
+  /**
+   * Return the name of the parameter being declared.
+   * @return the name of the parameter being declared
+   */
+  SimpleIdentifier get identifier;
+  /**
+   * Return the kind of this parameter.
+   * @return the kind of this parameter
+   */
+  ParameterKind get kind;
+}
+/**
+ * Instances of the class {@code FormalParameterList} represent the formal parameter list of a
+ * method declaration, function declaration, or function type alias.
+ * <p>
+ * While the grammar requires all optional formal parameters to follow all of the normal formal
+ * parameters and at most one grouping of optional formal parameters, this class does not enforce
+ * those constraints. All parameters are flattened into a single list, which can have any or all
+ * kinds of parameters (normal, named, and positional) in any order.
+ * <pre>
+ * formalParameterList ::=
+ * '(' ')'
+ * | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
+ * | '(' optionalFormalParameters ')'
+ * normalFormalParameters ::={@link NormalFormalParameter normalFormalParameter} (',' {@link NormalFormalParameter normalFormalParameter})
+ * optionalFormalParameters ::=
+ * optionalPositionalFormalParameters
+ * | namedFormalParameters
+ * optionalPositionalFormalParameters ::=
+ * '[' {@link DefaultFormalParameter positionalFormalParameter} (',' {@link DefaultFormalParameter positionalFormalParameter})* ']'
+ * namedFormalParameters ::=
+ * '{' {@link DefaultFormalParameter namedFormalParameter} (',' {@link DefaultFormalParameter namedFormalParameter})* '}'
+ * </pre>
+ */
+class FormalParameterList extends ASTNode {
+  /**
+   * The left parenthesis.
+   */
+  Token _leftParenthesis;
+  /**
+   * The parameters associated with the method.
+   */
+  NodeList<FormalParameter> _parameters;
+  /**
+   * The left square bracket ('[') or left curly brace ('{') introducing the optional parameters.
+   */
+  Token _leftDelimiter;
+  /**
+   * The right square bracket (']') or right curly brace ('}') introducing the optional parameters.
+   */
+  Token _rightDelimiter;
+  /**
+   * The right parenthesis.
+   */
+  Token _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._parameters = new NodeList<FormalParameter>(this);
+    this._leftParenthesis = leftParenthesis;
+    this._parameters.addAll(parameters);
+    this._leftDelimiter = leftDelimiter;
+    this._rightDelimiter = rightDelimiter;
+    this._rightParenthesis = rightParenthesis;
+  }
+  accept(ASTVisitor visitor) => visitor.visitFormalParameterList(this);
+  Token get beginToken => _leftParenthesis;
+  /**
+   * Return an array containing the elements representing the parameters in this list. The array
+   * will contain {@code null}s if the parameters in this list have not been resolved.
+   * @return the elements representing the parameters in this list
+   */
+  List<ParameterElement> get elements {
+    int count = _parameters.length;
+    List<ParameterElement> types = new List<ParameterElement>.fixedLength(count);
+    for (int i = 0; i < count; i++) {
+      types[i] = _parameters[i].element;
+    }
+    return types;
+  }
+  Token get endToken => _rightParenthesis;
+  /**
+   * Return the left square bracket ('[') or left curly brace ('{') introducing the optional
+   * parameters.
+   * @return the left square bracket ('[') or left curly brace ('{') introducing the optional
+   * parameters
+   */
+  Token get leftDelimiter => _leftDelimiter;
+  /**
+   * Return the left parenthesis.
+   * @return the left parenthesis
+   */
+  Token get leftParenthesis => _leftParenthesis;
+  /**
+   * Return the parameters associated with the method.
+   * @return the parameters associated with the method
+   */
+  NodeList<FormalParameter> get parameters => _parameters;
+  /**
+   * Return the right square bracket (']') or right curly brace ('}') introducing the optional
+   * parameters.
+   * @return the right square bracket (']') or right curly brace ('}') introducing the optional
+   * parameters
+   */
+  Token get rightDelimiter => _rightDelimiter;
+  /**
+   * Return the right parenthesis.
+   * @return the right parenthesis
+   */
+  Token get rightParenthesis => _rightParenthesis;
+  /**
+   * Set the left square bracket ('[') or left curly brace ('{') introducing the optional parameters
+   * to the given token.
+   * @param bracket the left delimiter introducing the optional parameters
+   */
+  void set leftDelimiter2(Token bracket) {
+    _leftDelimiter = bracket;
+  }
+  /**
+   * Set the left parenthesis to the given token.
+   * @param parenthesis the left parenthesis
+   */
+  void set leftParenthesis8(Token parenthesis) {
+    _leftParenthesis = parenthesis;
+  }
+  /**
+   * Set the right square bracket (']') or right curly brace ('}') introducing the optional
+   * parameters to the given token.
+   * @param bracket the right delimiter introducing the optional parameters
+   */
+  void set rightDelimiter2(Token bracket) {
+    _rightDelimiter = bracket;
+  }
+  /**
+   * Set the right parenthesis to the given token.
+   * @param parenthesis the right parenthesis
+   */
+  void set rightParenthesis8(Token parenthesis) {
+    _rightParenthesis = parenthesis;
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    _parameters.accept(visitor);
+  }
+}
+/**
+ * The abstract class {@code FunctionBody} defines the behavior common to objects representing the
+ * body of a function or method.
+ * <pre>
+ * functionBody ::={@link BlockFunctionBody blockFunctionBody}| {@link EmptyFunctionBody emptyFunctionBody}| {@link ExpressionFunctionBody expressionFunctionBody}</pre>
+ */
+abstract class FunctionBody extends ASTNode {
+}
+/**
+ * Instances of the class {@code FunctionDeclaration} wrap a {@link FunctionExpression function
+ * expression} as a top-level declaration.
+ * <pre>
+ * functionDeclaration ::=
+ * 'external' functionSignature
+ * | functionSignature {@link FunctionBody functionBody}functionSignature ::={@link Type returnType}? ('get' | 'set')? {@link SimpleIdentifier functionName} {@link FormalParameterList formalParameterList}</pre>
+ */
+class FunctionDeclaration extends CompilationUnitMember {
+  /**
+   * The token representing the 'external' keyword, or {@code null} if this is not an external
+   * function.
+   */
+  Token _externalKeyword;
+  /**
+   * The return type of the function, or {@code null} if no return type was declared.
+   */
+  TypeName _returnType;
+  /**
+   * The token representing the 'get' or 'set' keyword, or {@code null} if this is a function
+   * declaration rather than a property declaration.
+   */
+  Token _propertyKeyword;
+  /**
+   * The name of the function, or {@code null} if the function is not named.
+   */
+  SimpleIdentifier _name;
+  /**
+   * The function expression being wrapped.
+   */
+  FunctionExpression _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) : super(comment, metadata) {
+    this._externalKeyword = externalKeyword;
+    this._returnType = becomeParentOf(returnType);
+    this._propertyKeyword = propertyKeyword;
+    this._name = becomeParentOf(name);
+    this._functionExpression = becomeParentOf(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;
+  Token get endToken => _functionExpression.endToken;
+  /**
+   * Return the token representing the 'external' keyword, or {@code null} if this is not an
+   * external function.
+   * @return the token representing the 'external' keyword
+   */
+  Token get externalKeyword => _externalKeyword;
+  /**
+   * Return the function expression being wrapped.
+   * @return the function expression being wrapped
+   */
+  FunctionExpression get functionExpression => _functionExpression;
+  /**
+   * Return the name of the function, or {@code null} if the function is not named.
+   * @return the name of the function
+   */
+  SimpleIdentifier get name => _name;
+  /**
+   * Return the token representing the 'get' or 'set' keyword, or {@code null} if this is a function
+   * declaration rather than a property declaration.
+   * @return the token representing the 'get' or 'set' keyword
+   */
+  Token get propertyKeyword => _propertyKeyword;
+  /**
+   * Return the return type of the function, or {@code null} if no return type was declared.
+   * @return the return type of the function
+   */
+  TypeName get returnType => _returnType;
+  /**
+   * 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;
+  }
+  /**
+   * 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);
+  }
+  /**
+   * Set the name of the function to the given identifier.
+   * @param identifier the name of the function
+   */
+  void set name7(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;
+  }
+  /**
+   * Set the return type of the function to the given name.
+   * @param name the return type of the function
+   */
+  void set returnType3(TypeName name) {
+    _returnType = becomeParentOf(name);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_returnType, visitor);
+    safelyVisitChild(_name, visitor);
+    safelyVisitChild(_functionExpression, visitor);
+  }
+  Token get firstTokenAfterCommentAndMetadata {
+    if (_externalKeyword != null) {
+      return _externalKeyword;
+    }
+    if (_returnType != null) {
+      return _returnType.beginToken;
+    } else if (_propertyKeyword != null) {
+      return _propertyKeyword;
+    } else if (_name != null) {
+      return _name.beginToken;
+    }
+    return _functionExpression.beginToken;
+  }
+}
+/**
+ * Instances of the class {@code FunctionDeclarationStatement} wrap a {@link FunctionDeclarationfunction declaration} as a statement.
+ */
+class FunctionDeclarationStatement extends Statement {
+  /**
+   * The function declaration being wrapped.
+   */
+  FunctionDeclaration _functionDeclaration;
+  /**
+   * Initialize a newly created function declaration statement.
+   * @param functionDeclaration the the function declaration being wrapped
+   */
+  FunctionDeclarationStatement(FunctionDeclaration functionDeclaration) {
+    this._functionDeclaration = becomeParentOf(functionDeclaration);
+  }
+  accept(ASTVisitor visitor) => visitor.visitFunctionDeclarationStatement(this);
+  Token get beginToken => _functionDeclaration.beginToken;
+  Token get endToken => _functionDeclaration.endToken;
+  /**
+   * Return the function declaration being wrapped.
+   * @return the function declaration being wrapped
+   */
+  FunctionDeclaration get functionDeclaration => _functionDeclaration;
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_functionDeclaration, visitor);
+  }
+}
+/**
+ * Instances of the class {@code FunctionExpression} represent a function expression.
+ * <pre>
+ * functionExpression ::={@link FormalParameterList formalParameterList} {@link FunctionBody functionBody}</pre>
+ */
+class FunctionExpression extends Expression {
+  /**
+   * The parameters associated with the function.
+   */
+  FormalParameterList _parameters;
+  /**
+   * The body of the function, or {@code null} if this is an external function.
+   */
+  FunctionBody _body;
+  /**
+   * The element associated with the function, or {@code null} if the AST structure has not been
+   * resolved.
+   */
+  ExecutableElement _element;
+  /**
+   * 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._parameters = becomeParentOf(parameters);
+    this._body = becomeParentOf(body);
+  }
+  accept(ASTVisitor visitor) => visitor.visitFunctionExpression(this);
+  Token get beginToken {
+    if (_parameters != null) {
+      return _parameters.beginToken;
+    } else if (_body != null) {
+      return _body.beginToken;
+    }
+    throw new IllegalStateException("Non-external functions must have a body");
+  }
+  /**
+   * Return the body of the function, or {@code null} if this is an external function.
+   * @return the body of the function
+   */
+  FunctionBody get body => _body;
+  /**
+   * Return the element associated with this function, or {@code null} if the AST structure has not
+   * been resolved.
+   * @return the element associated with this function
+   */
+  ExecutableElement get element => _element;
+  Token get endToken {
+    if (_body != null) {
+      return _body.endToken;
+    } else if (_parameters != null) {
+      return _parameters.endToken;
+    }
+    throw new IllegalStateException("Non-external functions must have a body");
+  }
+  /**
+   * Return the parameters associated with the function.
+   * @return the parameters associated with the function
+   */
+  FormalParameterList get parameters => _parameters;
+  /**
+   * Set the body of the function to the given function body.
+   * @param functionBody the body of the function
+   */
+  void set body7(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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_parameters, visitor);
+    safelyVisitChild(_body, visitor);
+  }
+}
+/**
+ * Instances of the class {@code FunctionExpressionInvocation} represent the invocation of a
+ * function resulting from evaluating an expression. Invocations of methods and other forms of
+ * functions are represented by {@link MethodInvocation method invocation} nodes. Invocations of
+ * getters and setters are represented by either {@link PrefixedIdentifier prefixed identifier} or{@link PropertyAccess property access} nodes.
+ * <pre>
+ * functionExpressionInvoction ::={@link Expression function} {@link ArgumentList argumentList}</pre>
+ */
+class FunctionExpressionInvocation extends Expression {
+  /**
+   * The expression producing the function being invoked.
+   */
+  Expression _function;
+  /**
+   * The list of arguments to the function.
+   */
+  ArgumentList _argumentList;
+  /**
+   * The element associated with the function being invoked, or {@code null} if the AST structure
+   * has not been resolved or the function could not be resolved.
+   */
+  ExecutableElement _element;
+  /**
+   * 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._function = becomeParentOf(function);
+    this._argumentList = becomeParentOf(argumentList);
+  }
+  accept(ASTVisitor visitor) => visitor.visitFunctionExpressionInvocation(this);
+  /**
+   * Return the list of arguments to the method.
+   * @return the list of arguments to the method
+   */
+  ArgumentList get argumentList => _argumentList;
+  Token get beginToken => _function.beginToken;
+  /**
+   * Return the element associated with the function being invoked, or {@code null} if the AST
+   * structure has not been resolved or the function could not be resolved. One common example of
+   * the latter case is an expression whose value can change over time.
+   * @return the element associated with the function being invoked
+   */
+  ExecutableElement get element => _element;
+  Token get endToken => _argumentList.endToken;
+  /**
+   * Return the expression producing the function being invoked.
+   * @return the expression producing the function being invoked
+   */
+  Expression get function => _function;
+  /**
+   * 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);
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_function, visitor);
+    safelyVisitChild(_argumentList, visitor);
+  }
+}
+/**
+ * Instances of the class {@code FunctionTypeAlias} represent a function type alias.
+ * <pre>
+ * functionTypeAlias ::=
+ * functionPrefix {@link TypeParameterList typeParameterList}? {@link FormalParameterList formalParameterList} ';'
+ * functionPrefix ::={@link TypeName returnType}? {@link SimpleIdentifier name}</pre>
+ */
+class FunctionTypeAlias extends TypeAlias {
+  /**
+   * The name of the return type of the function type being defined, or {@code null} if no return
+   * type was given.
+   */
+  TypeName _returnType;
+  /**
+   * The name of the function type being declared.
+   */
+  SimpleIdentifier _name;
+  /**
+   * The type parameters for the function type, or {@code null} if the function type does not have
+   * any type parameters.
+   */
+  TypeParameterList _typeParameters;
+  /**
+   * The parameters associated with the function type.
+   */
+  FormalParameterList _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) : super(comment, metadata, keyword, semicolon) {
+    this._returnType = becomeParentOf(returnType);
+    this._name = becomeParentOf(name);
+    this._typeParameters = becomeParentOf(typeParameters);
+    this._parameters = becomeParentOf(parameters);
+  }
+  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;
+  /**
+   * Return the name of the function type being declared.
+   * @return the name of the function type being declared
+   */
+  SimpleIdentifier get name => _name;
+  /**
+   * Return the parameters associated with the function type.
+   * @return the parameters associated with the function type
+   */
+  FormalParameterList get parameters => _parameters;
+  /**
+   * Return the name of the return type of the function type being defined, or {@code null} if no
+   * return type was given.
+   * @return the name of the return type of the function type being defined
+   */
+  TypeName get returnType => _returnType;
+  /**
+   * Return the type parameters for the function type, or {@code null} if the function type does not
+   * have any type parameters.
+   * @return the type parameters for the function type
+   */
+  TypeParameterList get typeParameters => _typeParameters;
+  /**
+   * 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);
+  }
+  /**
+   * 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);
+  }
+  /**
+   * 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) {
+    _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 visitChildren(ASTVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_returnType, visitor);
+    safelyVisitChild(_name, visitor);
+    safelyVisitChild(_typeParameters, visitor);
+    safelyVisitChild(_parameters, visitor);
+  }
+}
+/**
+ * Instances of the class {@code FunctionTypedFormalParameter} represent a function-typed formal
+ * parameter.
+ * <pre>
+ * functionSignature ::={@link TypeName returnType}? {@link SimpleIdentifier identifier} {@link FormalParameterList formalParameterList}</pre>
+ */
+class FunctionTypedFormalParameter extends NormalFormalParameter {
+  /**
+   * The return type of the function, or {@code null} if the function does not have a return type.
+   */
+  TypeName _returnType;
+  /**
+   * The parameters of the function-typed parameter.
+   */
+  FormalParameterList _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) : super(comment, metadata, identifier) {
+    this._returnType = becomeParentOf(returnType);
+    this._parameters = becomeParentOf(parameters);
+  }
+  accept(ASTVisitor visitor) => visitor.visitFunctionTypedFormalParameter(this);
+  Token get beginToken {
+    if (_returnType != null) {
+      return _returnType.beginToken;
+    }
+    return identifier.beginToken;
+  }
+  Token get endToken => _parameters.endToken;
+  /**
+   * Return the parameters of the function-typed parameter.
+   * @return the parameters of the function-typed parameter
+   */
+  FormalParameterList get parameters => _parameters;
+  /**
+   * Return the return type of the function, or {@code null} if the function does not have a return
+   * type.
+   * @return the return type of the function
+   */
+  TypeName get returnType => _returnType;
+  bool isConst() => false;
+  bool isFinal() => false;
+  /**
+   * 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);
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_returnType, visitor);
+    safelyVisitChild(identifier, visitor);
+    safelyVisitChild(_parameters, visitor);
+  }
+}
+/**
+ * Instances of the class {@code HideCombinator} represent a combinator that restricts the names
+ * being imported to those that are not in a given list.
+ * <pre>
+ * hideCombinator ::=
+ * 'hide' {@link SimpleIdentifier identifier} (',' {@link SimpleIdentifier identifier})
+ * </pre>
+ */
+class HideCombinator extends Combinator {
+  /**
+   * The list of names from the library that are hidden by this combinator.
+   */
+  NodeList<SimpleIdentifier> _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) : super(keyword) {
+    this._hiddenNames = new NodeList<SimpleIdentifier>(this);
+    this._hiddenNames.addAll(hiddenNames);
+  }
+  accept(ASTVisitor visitor) => visitor.visitHideCombinator(this);
+  Token get endToken => _hiddenNames.endToken;
+  /**
+   * Return the list of names from the library that are hidden by this combinator.
+   * @return the list of names from the library that are hidden by this combinator
+   */
+  NodeList<SimpleIdentifier> get hiddenNames => _hiddenNames;
+  void visitChildren(ASTVisitor<Object> visitor) {
+    _hiddenNames.accept(visitor);
+  }
+}
+/**
+ * The abstract class {@code Identifier} defines the behavior common to nodes that represent an
+ * identifier.
+ * <pre>
+ * identifier ::={@link SimpleIdentifier simpleIdentifier}| {@link PrefixedIdentifier prefixedIdentifier}</pre>
+ */
+abstract class Identifier extends Expression {
+  /**
+   * Return {@code true} if the given name is visible only within the library in which it is
+   * declared.
+   * @param name the name being tested
+   * @return {@code true} if the given name is private
+   */
+  static bool isPrivateName(String name) => name.startsWith("_");
+  /**
+   * The element associated with this identifier, or {@code null} if the AST structure has not been
+   * resolved or if this identifier could not be resolved.
+   */
+  Element _element;
+  /**
+   * Return the element associated with this identifier, or {@code null} if the AST structure has
+   * not been resolved or if this identifier could not be resolved. One example of the latter case
+   * is an identifier that is not defined within the scope in which it appears.
+   * @return the element associated with this identifier
+   */
+  Element get element => _element;
+  /**
+   * Return the lexical representation of the identifier.
+   * @return the lexical representation of the identifier
+   */
+  String get name;
+  bool isAssignable() => true;
+  /**
+   * 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;
+  }
+}
+/**
+ * Instances of the class {@code IfStatement} represent an if statement.
+ * <pre>
+ * ifStatement ::=
+ * 'if' '(' {@link Expression expression} ')' {@link Statement thenStatement} ('else' {@link Statement elseStatement})?
+ * </pre>
+ */
+class IfStatement extends Statement {
+  /**
+   * The token representing the 'if' keyword.
+   */
+  Token _ifKeyword;
+  /**
+   * The left parenthesis.
+   */
+  Token _leftParenthesis;
+  /**
+   * The condition used to determine which of the statements is executed next.
+   */
+  Expression _condition;
+  /**
+   * The right parenthesis.
+   */
+  Token _rightParenthesis;
+  /**
+   * The statement that is executed if the condition evaluates to {@code true}.
+   */
+  Statement _thenStatement;
+  /**
+   * The token representing the 'else' keyword.
+   */
+  Token _elseKeyword;
+  /**
+   * The statement that is executed if the condition evaluates to {@code false}, or {@code null} if
+   * there is no else statement.
+   */
+  Statement _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._ifKeyword = ifKeyword;
+    this._leftParenthesis = leftParenthesis;
+    this._condition = becomeParentOf(condition);
+    this._rightParenthesis = rightParenthesis;
+    this._thenStatement = becomeParentOf(thenStatement);
+    this._elseKeyword = elseKeyword;
+    this._elseStatement = becomeParentOf(elseStatement);
+  }
+  accept(ASTVisitor visitor) => visitor.visitIfStatement(this);
+  Token get beginToken => _ifKeyword;
+  /**
+   * Return the condition used to determine which of the statements is executed next.
+   * @return the condition used to determine which statement is executed next
+   */
+  Expression get condition => _condition;
+  /**
+   * Return the token representing the 'else' keyword.
+   * @return the token representing the 'else' keyword
+   */
+  Token get elseKeyword => _elseKeyword;
+  /**
+   * Return the statement that is executed if the condition evaluates to {@code false}, or{@code null} if there is no else statement.
+   * @return the statement that is executed if the condition evaluates to {@code false}
+   */
+  Statement get elseStatement => _elseStatement;
+  Token get endToken {
+    if (_elseStatement != null) {
+      return _elseStatement.endToken;
+    }
+    return _thenStatement.endToken;
+  }
+  /**
+   * Return the token representing the 'if' keyword.
+   * @return the token representing the 'if' keyword
+   */
+  Token get ifKeyword => _ifKeyword;
+  /**
+   * Return the left parenthesis.
+   * @return the left parenthesis
+   */
+  Token get leftParenthesis => _leftParenthesis;
+  /**
+   * Return the right parenthesis.
+   * @return the right parenthesis
+   */
+  Token get rightParenthesis => _rightParenthesis;
+  /**
+   * Return the statement that is executed if the condition evaluates to {@code true}.
+   * @return the statement that is executed if the condition evaluates to {@code true}
+   */
+  Statement get thenStatement => _thenStatement;
+  /**
+   * Set the condition used to determine which of the statements is executed next to the given
+   * expression.
+   * @param expression the condition used to determine which statement is executed next
+   */
+  void set condition6(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;
+  }
+  /**
+   * 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) {
+    _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;
+  }
+  /**
+   * Set the left parenthesis to the given token.
+   * @param leftParenthesis the left parenthesis
+   */
+  void set leftParenthesis9(Token leftParenthesis) {
+    this._leftParenthesis = leftParenthesis;
+  }
+  /**
+   * Set the right parenthesis to the given token.
+   * @param rightParenthesis the right parenthesis
+   */
+  void set rightParenthesis9(Token rightParenthesis) {
+    this._rightParenthesis = rightParenthesis;
+  }
+  /**
+   * 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) {
+    _thenStatement = becomeParentOf(statement);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_condition, visitor);
+    safelyVisitChild(_thenStatement, visitor);
+    safelyVisitChild(_elseStatement, visitor);
+  }
+}
+/**
+ * Instances of the class {@code ImplementsClause} represent the "implements" clause in an class
+ * declaration.
+ * <pre>
+ * implementsClause ::=
+ * 'implements' {@link TypeName superclass} (',' {@link TypeName superclass})
+ * </pre>
+ */
+class ImplementsClause extends ASTNode {
+  /**
+   * The token representing the 'implements' keyword.
+   */
+  Token _keyword;
+  /**
+   * The interfaces that are being implemented.
+   */
+  NodeList<TypeName> _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._interfaces = new NodeList<TypeName>(this);
+    this._keyword = keyword;
+    this._interfaces.addAll(interfaces);
+  }
+  accept(ASTVisitor visitor) => visitor.visitImplementsClause(this);
+  Token get beginToken => _keyword;
+  Token get endToken => _interfaces.endToken;
+  /**
+   * Return the list of the interfaces that are being implemented.
+   * @return the list of the interfaces that are being implemented
+   */
+  NodeList<TypeName> get interfaces => _interfaces;
+  /**
+   * Return the token representing the 'implements' keyword.
+   * @return the token representing the 'implements' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    _interfaces.accept(visitor);
+  }
+}
+/**
+ * Instances of the class {@code ImportDirective} represent an import directive.
+ * <pre>
+ * importDirective ::={@link Annotation metadata} 'import' {@link StringLiteral libraryUri} ('as' identifier)? {@link Combinator combinator}* ';'
+ * </pre>
+ */
+class ImportDirective extends NamespaceDirective {
+  /**
+   * The token representing the 'as' token, or {@code null} if the imported names are not prefixed.
+   */
+  Token _asToken;
+  /**
+   * The prefix to be used with the imported names, or {@code null} if the imported names are not
+   * prefixed.
+   */
+  SimpleIdentifier _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) : super(comment, metadata, keyword, libraryUri, combinators, semicolon) {
+    this._asToken = asToken;
+    this._prefix = becomeParentOf(prefix);
+  }
+  accept(ASTVisitor visitor) => visitor.visitImportDirective(this);
+  /**
+   * Return the token representing the 'as' token, or {@code null} if the imported names are not
+   * prefixed.
+   * @return the token representing the 'as' token
+   */
+  Token get asToken => _asToken;
+  /**
+   * Return the prefix to be used with the imported names, or {@code null} if the imported names are
+   * not prefixed.
+   * @return the prefix to be used with the imported names
+   */
+  SimpleIdentifier get prefix => _prefix;
+  /**
+   * 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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(libraryUri, visitor);
+    safelyVisitChild(_prefix, visitor);
+    combinators.accept(visitor);
+  }
+}
+/**
+ * Instances of the class {@code IndexExpression} represent an index expression.
+ * <pre>
+ * indexExpression ::={@link Expression target} '[' {@link Expression index} ']'
+ * </pre>
+ */
+class IndexExpression extends Expression {
+  /**
+   * The expression used to compute the object being indexed, or {@code null} if this index
+   * expression is part of a cascade expression.
+   */
+  Expression _target;
+  /**
+   * The period ("..") before a cascaded index expression, or {@code null} if this index expression
+   * is not part of a cascade expression.
+   */
+  Token _period;
+  /**
+   * The left square bracket.
+   */
+  Token _leftBracket;
+  /**
+   * The expression used to compute the index.
+   */
+  Expression _index;
+  /**
+   * The right square bracket.
+   */
+  Token _rightBracket;
+  /**
+   * The element associated with the operator, or {@code null} if the AST structure has not been
+   * resolved or if the operator could not be resolved.
+   */
+  MethodElement _element;
+  /**
+   * 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.con1(Expression target, Token leftBracket, Expression index, Token rightBracket) {
+    _jtd_constructor_55_impl(target, leftBracket, index, rightBracket);
+  }
+  _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 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.con2(Token period, Token leftBracket, Expression index, Token rightBracket) {
+    _jtd_constructor_56_impl(period, leftBracket, index, rightBracket);
+  }
+  _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;
+  }
+  accept(ASTVisitor visitor) => visitor.visitIndexExpression(this);
+  /**
+   * Return the expression used to compute the object being indexed, or {@code null} if this index
+   * expression is part of a cascade expression.
+   * @return the expression used to compute the object being indexed
+   * @see #getRealTarget()
+   */
+  Expression get array => _target;
+  Token get beginToken {
+    if (_target != null) {
+      return _target.beginToken;
+    }
+    return _period;
+  }
+  /**
+   * Return the element associated with the operator, or {@code null} if the AST structure has not
+   * been resolved or if the operator could not be resolved. One example of the latter case is an
+   * operator that is not defined for the type of the left-hand operand.
+   * @return the element associated with this operator
+   */
+  MethodElement get element => _element;
+  Token get endToken => _rightBracket;
+  /**
+   * Return the expression used to compute the index.
+   * @return the expression used to compute the index
+   */
+  Expression get index => _index;
+  /**
+   * Return the left square bracket.
+   * @return the left square bracket
+   */
+  Token get leftBracket => _leftBracket;
+  /**
+   * Return the period ("..") before a cascaded index expression, or {@code null} if this index
+   * expression is not part of a cascade expression.
+   * @return the period ("..") before a cascaded index expression
+   */
+  Token get period => _period;
+  /**
+   * Return the expression used to compute the object being indexed. If this index expression is not
+   * part of a cascade expression, then this is the same as {@link #getArray()}. If this index
+   * expression is part of a cascade expression, then the target expression stored with the cascade
+   * expression is returned.
+   * @return the expression used to compute the object being indexed
+   * @see #getArray()
+   */
+  Expression get realTarget {
+    if (isCascaded()) {
+      ASTNode ancestor = parent;
+      while (ancestor is! CascadeExpression) {
+        if (ancestor == null) {
+          return _target;
+        }
+        ancestor = ancestor.parent;
+      }
+      return (ancestor as CascadeExpression).target;
+    }
+    return _target;
+  }
+  /**
+   * Return the right square bracket.
+   * @return the right square bracket
+   */
+  Token get rightBracket => _rightBracket;
+  /**
+   * Return {@code true} if this expression is computing a right-hand value.
+   * <p>
+   * Note that {@link #inGetterContext()} and {@link #inSetterContext()} are not opposites, nor are
+   * they mutually exclusive. In other words, it is possible for both methods to return {@code true}when invoked on the same node.
+   * @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) {
+        return false;
+      }
+    }
+    return true;
+  }
+  /**
+   * Return {@code true} if this expression is computing a left-hand value.
+   * <p>
+   * Note that {@link #inGetterContext()} and {@link #inSetterContext()} are not opposites, nor are
+   * they mutually exclusive. In other words, it is possible for both methods to return {@code true}when invoked on the same node.
+   * @return {@code true} if this expression is in a context where the operator '[]=' will be
+   * invoked
+   */
+  bool inSetterContext() {
+    ASTNode parent5 = parent;
+    if (parent5 is PrefixExpression) {
+      return (parent5 as PrefixExpression).operator.type.isIncrementOperator();
+    } else if (parent5 is PostfixExpression) {
+      return true;
+    } else if (parent5 is AssignmentExpression) {
+      return (parent5 as AssignmentExpression).leftHandSide == this;
+    }
+    return false;
+  }
+  bool isAssignable() => true;
+  /**
+   * Return {@code true} if this expression is cascaded. If it is, then the target of this
+   * 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;
+  /**
+   * 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) {
+    _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;
+  }
+  /**
+   * 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) {
+    _index = becomeParentOf(expression);
+  }
+  /**
+   * Set the left square bracket to the given token.
+   * @param bracket the left square bracket
+   */
+  void set leftBracket4(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;
+  }
+  /**
+   * Set the right square bracket to the given token.
+   * @param bracket the right square bracket
+   */
+  void set rightBracket4(Token bracket) {
+    _rightBracket = bracket;
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_target, visitor);
+    safelyVisitChild(_index, visitor);
+  }
+}
+/**
+ * Instances of the class {@code InstanceCreationExpression} represent an instance creation
+ * expression.
+ * <pre>
+ * newExpression ::=
+ * ('new' | 'const') {@link TypeName type} ('.' {@link SimpleIdentifier identifier})? {@link ArgumentList argumentList}</pre>
+ */
+class InstanceCreationExpression extends Expression {
+  /**
+   * The keyword used to indicate how an object should be created.
+   */
+  Token _keyword;
+  /**
+   * The name of the constructor to be invoked.
+   */
+  ConstructorName _constructorName;
+  /**
+   * The list of arguments to the constructor.
+   */
+  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 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._keyword = keyword;
+    this._constructorName = becomeParentOf(constructorName);
+    this._argumentList = becomeParentOf(argumentList);
+  }
+  accept(ASTVisitor visitor) => visitor.visitInstanceCreationExpression(this);
+  /**
+   * Return the list of arguments to the constructor.
+   * @return the list of arguments to the constructor
+   */
+  ArgumentList get argumentList => _argumentList;
+  Token get beginToken => _keyword;
+  /**
+   * Return the name of the constructor to be invoked.
+   * @return the name of the constructor to be invoked
+   */
+  ConstructorName 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 constructor
+   */
+  ConstructorElement get element => _element;
+  Token get endToken => _argumentList.endToken;
+  /**
+   * Return the keyword used to indicate how an object should be created.
+   * @return the keyword used to indicate how an object should be created
+   */
+  Token get keyword => _keyword;
+  /**
+   * 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);
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_constructorName, visitor);
+    safelyVisitChild(_argumentList, visitor);
+  }
+}
+/**
+ * Instances of the class {@code IntegerLiteral} represent an integer literal expression.
+ * <pre>
+ * integerLiteral ::=
+ * decimalIntegerLiteral
+ * | hexidecimalIntegerLiteral
+ * decimalIntegerLiteral ::=
+ * decimalDigit+
+ * hexidecimalIntegerLiteral ::=
+ * '0x' hexidecimalDigit+
+ * | '0X' hexidecimalDigit+
+ * </pre>
+ */
+class IntegerLiteral extends Literal {
+  /**
+   * The token representing the literal.
+   */
+  Token _literal;
+  /**
+   * The value of the literal.
+   */
+  int _value = 0;
+  /**
+   * Initialize a newly created integer literal.
+   * @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) {
+    this._literal = literal;
+    this._value = value;
+  }
+  /**
+   * Initialize a newly created integer literal.
+   * @param token 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);
+  }
+  accept(ASTVisitor visitor) => visitor.visitIntegerLiteral(this);
+  Token get beginToken => _literal;
+  Token get endToken => _literal;
+  /**
+   * Return the token representing the literal.
+   * @return the token representing the literal
+   */
+  Token get literal => _literal;
+  /**
+   * Return the value of the literal.
+   * @return the value of the literal
+   */
+  int get value => _value;
+  /**
+   * 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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+  }
+}
+/**
+ * The abstract class {@code InterpolationElement} defines the behavior common to elements within a{@link StringInterpolation string interpolation}.
+ * <pre>
+ * interpolationElement ::={@link InterpolationExpression interpolationExpression}| {@link InterpolationString interpolationString}</pre>
+ */
+abstract class InterpolationElement extends ASTNode {
+}
+/**
+ * Instances of the class {@code InterpolationExpression} represent an expression embedded in a
+ * string interpolation.
+ * <pre>
+ * interpolationExpression ::=
+ * '$' {@link SimpleIdentifier identifier}| '$' '{' {@link Expression expression} '}'
+ * </pre>
+ */
+class InterpolationExpression extends InterpolationElement {
+  /**
+   * The token used to introduce the interpolation expression; either '$' if the expression is a
+   * simple identifier or '${' if the expression is a full expression.
+   */
+  Token _leftBracket;
+  /**
+   * The expression to be evaluated for the value to be converted into a string.
+   */
+  Expression _expression;
+  /**
+   * The right curly bracket, or {@code null} if the expression is an identifier without brackets.
+   */
+  Token _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._leftBracket = leftBracket;
+    this._expression = becomeParentOf(expression);
+    this._rightBracket = rightBracket;
+  }
+  accept(ASTVisitor visitor) => visitor.visitInterpolationExpression(this);
+  Token get beginToken => _leftBracket;
+  Token get endToken {
+    if (_rightBracket != null) {
+      return _rightBracket;
+    }
+    return _expression.endToken;
+  }
+  /**
+   * Return the expression to be evaluated for the value to be converted into a string.
+   * @return the expression to be evaluated for the value to be converted into a string
+   */
+  Expression get expression => _expression;
+  /**
+   * Return the left curly bracket.
+   * @return the left curly bracket
+   */
+  Token get leftBracket => _leftBracket;
+  /**
+   * Return the right curly bracket.
+   * @return the right curly bracket
+   */
+  Token get rightBracket => _rightBracket;
+  /**
+   * Set the expression to be evaluated for the value to be converted into a string to the given
+   * 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);
+  }
+  /**
+   * Set the left curly bracket to the given token.
+   * @param leftBracket the left curly bracket
+   */
+  void set leftBracket5(Token leftBracket) {
+    this._leftBracket = leftBracket;
+  }
+  /**
+   * Set the right curly bracket to the given token.
+   * @param rightBracket the right curly bracket
+   */
+  void set rightBracket5(Token rightBracket) {
+    this._rightBracket = rightBracket;
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_expression, visitor);
+  }
+}
+/**
+ * Instances of the class {@code InterpolationString} represent a non-empty substring of an
+ * interpolated string.
+ * <pre>
+ * interpolationString ::=
+ * characters
+ * </pre>
+ */
+class InterpolationString extends InterpolationElement {
+  /**
+   * The characters that will be added to the string.
+   */
+  Token _contents;
+  /**
+   * The value of the literal.
+   */
+  String _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._contents = contents;
+    this._value = value;
+  }
+  accept(ASTVisitor visitor) => visitor.visitInterpolationString(this);
+  Token get beginToken => _contents;
+  /**
+   * Return the characters that will be added to the string.
+   * @return the characters that will be added to the string
+   */
+  Token get contents => _contents;
+  Token get endToken => _contents;
+  /**
+   * Return the value of the literal.
+   * @return the value of the literal
+   */
+  String get value => _value;
+  /**
+   * 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) {
+    _contents = string;
+  }
+  /**
+   * Set the value of the literal to the given string.
+   * @param string the value of the literal
+   */
+  void set value7(String string) {
+    _value = string;
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+  }
+}
+/**
+ * Instances of the class {@code IsExpression} represent an is expression.
+ * <pre>
+ * isExpression ::={@link Expression expression} 'is' '!'? {@link TypeName type}</pre>
+ */
+class IsExpression extends Expression {
+  /**
+   * The expression used to compute the value whose type is being tested.
+   */
+  Expression _expression;
+  /**
+   * The is operator.
+   */
+  Token _isOperator;
+  /**
+   * The not operator, or {@code null} if the sense of the test is not negated.
+   */
+  Token _notOperator;
+  /**
+   * The name of the type being tested for.
+   */
+  TypeName _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._expression = becomeParentOf(expression);
+    this._isOperator = isOperator;
+    this._notOperator = notOperator;
+    this._type = becomeParentOf(type);
+  }
+  accept(ASTVisitor visitor) => visitor.visitIsExpression(this);
+  Token get beginToken => _expression.beginToken;
+  Token get endToken => _type.endToken;
+  /**
+   * Return the expression used to compute the value whose type is being tested.
+   * @return the expression used to compute the value whose type is being tested
+   */
+  Expression get expression => _expression;
+  /**
+   * Return the is operator being applied.
+   * @return the is operator being applied
+   */
+  Token get isOperator => _isOperator;
+  /**
+   * Return the not operator being applied.
+   * @return the not operator being applied
+   */
+  Token get notOperator => _notOperator;
+  /**
+   * Return the name of the type being tested for.
+   * @return the name of the type being tested for
+   */
+  TypeName get type => _type;
+  /**
+   * Set the expression used to compute the value whose type is being tested to the given
+   * expression.
+   * @param expression the expression used to compute the value whose type is being tested
+   */
+  void set expression7(Expression expression) {
+    this._expression = becomeParentOf(expression);
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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) {
+    this._type = becomeParentOf(name);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_expression, visitor);
+    safelyVisitChild(_type, visitor);
+  }
+}
+/**
+ * Instances of the class {@code Label} represent a label.
+ * <pre>
+ * label ::={@link SimpleIdentifier label} ':'
+ * </pre>
+ */
+class Label extends ASTNode {
+  /**
+   * The label being associated with the statement.
+   */
+  SimpleIdentifier _label;
+  /**
+   * The colon that separates the label from the statement.
+   */
+  Token _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._label = becomeParentOf(label);
+    this._colon = colon;
+  }
+  accept(ASTVisitor visitor) => visitor.visitLabel(this);
+  Token get beginToken => _label.beginToken;
+  /**
+   * Return the colon that separates the label from the statement.
+   * @return the colon that separates the label from the statement
+   */
+  Token get colon => _colon;
+  Token get endToken => _colon;
+  /**
+   * Return the label being associated with the statement.
+   * @return the label being associated with the statement
+   */
+  SimpleIdentifier get label => _label;
+  /**
+   * 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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_label, visitor);
+  }
+}
+/**
+ * Instances of the class {@code LabeledStatement} represent a statement that has a label associated
+ * with them.
+ * <pre>
+ * labeledStatement ::={@link Label label}+ {@link Statement statement}</pre>
+ */
+class LabeledStatement extends Statement {
+  /**
+   * The labels being associated with the statement.
+   */
+  NodeList<Label> _labels;
+  /**
+   * The statement with which the labels are being associated.
+   */
+  Statement _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._labels = new NodeList<Label>(this);
+    this._labels.addAll(labels);
+    this._statement = becomeParentOf(statement);
+  }
+  accept(ASTVisitor visitor) => visitor.visitLabeledStatement(this);
+  Token get beginToken {
+    if (!_labels.isEmpty) {
+      return _labels.beginToken;
+    }
+    return _statement.beginToken;
+  }
+  Token get endToken => _statement.endToken;
+  /**
+   * Return the labels being associated with the statement.
+   * @return the labels being associated with the statement
+   */
+  NodeList<Label> get labels => _labels;
+  /**
+   * Return the statement with which the labels are being associated.
+   * @return the statement with which the labels are being associated
+   */
+  Statement get statement => _statement;
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    _labels.accept(visitor);
+    safelyVisitChild(_statement, visitor);
+  }
+}
+/**
+ * Instances of the class {@code LibraryDirective} represent a library directive.
+ * <pre>
+ * libraryDirective ::={@link Annotation metadata} 'library' {@link Identifier name} ';'
+ * </pre>
+ */
+class LibraryDirective extends Directive {
+  /**
+   * The token representing the 'library' token.
+   */
+  Token _libraryToken;
+  /**
+   * The name of the library being defined.
+   */
+  LibraryIdentifier _name;
+  /**
+   * The semicolon terminating the directive.
+   */
+  Token _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) : super(comment, metadata) {
+    this._libraryToken = libraryToken;
+    this._name = becomeParentOf(name);
+    this._semicolon = semicolon;
+  }
+  accept(ASTVisitor visitor) => visitor.visitLibraryDirective(this);
+  Token get endToken => _semicolon;
+  Token get keyword => _libraryToken;
+  /**
+   * Return the token representing the 'library' token.
+   * @return the token representing the 'library' token
+   */
+  Token get libraryToken => _libraryToken;
+  /**
+   * Return the name of the library being defined.
+   * @return the name of the library being defined
+   */
+  LibraryIdentifier get name => _name;
+  /**
+   * Return the semicolon terminating the directive.
+   * @return the semicolon terminating the directive
+   */
+  Token get semicolon => _semicolon;
+  /**
+   * 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;
+  }
+  /**
+   * 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);
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_name, visitor);
+  }
+  Token get firstTokenAfterCommentAndMetadata => _libraryToken;
+}
+/**
+ * Instances of the class {@code LibraryIdentifier} represent the identifier for a library.
+ * <pre>
+ * libraryIdentifier ::={@link SimpleIdentifier component} ('.' {@link SimpleIdentifier component})
+ * </pre>
+ */
+class LibraryIdentifier extends Identifier {
+  /**
+   * The components of the identifier.
+   */
+  NodeList<SimpleIdentifier> _components;
+  /**
+   * Initialize a newly created prefixed identifier.
+   * @param components the components of the identifier
+   */
+  LibraryIdentifier(List<SimpleIdentifier> components) {
+    this._components = new NodeList<SimpleIdentifier>(this);
+    this._components.addAll(components);
+  }
+  accept(ASTVisitor visitor) => visitor.visitLibraryIdentifier(this);
+  Token get beginToken => _components.beginToken;
+  /**
+   * Return the components of the identifier.
+   * @return the components of the identifier
+   */
+  NodeList<SimpleIdentifier> get components => _components;
+  Token get endToken => _components.endToken;
+  String get name {
+    StringBuffer builder = new StringBuffer();
+    bool needsPeriod = false;
+    for (SimpleIdentifier identifier in _components) {
+      if (needsPeriod) {
+        builder.add(".");
+      } else {
+        needsPeriod = true;
+      }
+      builder.add(identifier.name);
+    }
+    return builder.toString();
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    _components.accept(visitor);
+  }
+}
+/**
+ * Instances of the class {@code ListLiteral} represent a list literal.
+ * <pre>
+ * listLiteral ::=
+ * 'const'? ('<' {@link TypeName type} '>')? '[' ({@link Expression expressionList} ','?)? ']'
+ * </pre>
+ */
+class ListLiteral extends TypedLiteral {
+  /**
+   * The left square bracket.
+   */
+  Token _leftBracket;
+  /**
+   * The expressions used to compute the elements of the list.
+   */
+  NodeList<Expression> _elements;
+  /**
+   * The right square bracket.
+   */
+  Token _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) : super(modifier, typeArguments) {
+    this._elements = new NodeList<Expression>(this);
+    this._leftBracket = leftBracket;
+    this._elements.addAll(elements);
+    this._rightBracket = rightBracket;
+  }
+  accept(ASTVisitor visitor) => visitor.visitListLiteral(this);
+  Token get beginToken {
+    Token token = modifier;
+    if (token != null) {
+      return token;
+    }
+    TypeArgumentList typeArguments6 = typeArguments;
+    if (typeArguments6 != null) {
+      return typeArguments6.beginToken;
+    }
+    return _leftBracket;
+  }
+  /**
+   * Return the expressions used to compute the elements of the list.
+   * @return the expressions used to compute the elements of the list
+   */
+  NodeList<Expression> get elements => _elements;
+  Token get endToken => _rightBracket;
+  /**
+   * Return the left square bracket.
+   * @return the left square bracket
+   */
+  Token get leftBracket => _leftBracket;
+  /**
+   * Return the right square bracket.
+   * @return the right square bracket
+   */
+  Token get rightBracket => _rightBracket;
+  /**
+   * Set the left square bracket to the given token.
+   * @param bracket the left square bracket
+   */
+  void set leftBracket6(Token bracket) {
+    _leftBracket = bracket;
+  }
+  /**
+   * Set the right square bracket to the given token.
+   * @param bracket the right square bracket
+   */
+  void set rightBracket6(Token bracket) {
+    _rightBracket = bracket;
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    _elements.accept(visitor);
+  }
+}
+/**
+ * The abstract class {@code Literal} defines the behavior common to nodes that represent a literal
+ * expression.
+ * <pre>
+ * literal ::={@link BooleanLiteral booleanLiteral}| {@link DoubleLiteral doubleLiteral}| {@link IntegerLiteral integerLiteral}| {@link ListLiteral listLiteral}| {@link MapLiteral mapLiteral}| {@link NullLiteral nullLiteral}| {@link StringLiteral stringLiteral}</pre>
+ */
+abstract class Literal extends Expression {
+}
+/**
+ * Instances of the class {@code MapLiteral} represent a literal map.
+ * <pre>
+ * mapLiteral ::=
+ * 'const'? ('<' {@link TypeName type} '>')? '{' ({@link MapLiteralEntry entry} (',' {@link MapLiteralEntry entry})* ','?)? '}'
+ * </pre>
+ */
+class MapLiteral extends TypedLiteral {
+  /**
+   * The left curly bracket.
+   */
+  Token _leftBracket;
+  /**
+   * The entries in the map.
+   */
+  NodeList<MapLiteralEntry> _entries;
+  /**
+   * The right curly bracket.
+   */
+  Token _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) : super(modifier, typeArguments) {
+    this._entries = new NodeList<MapLiteralEntry>(this);
+    this._leftBracket = leftBracket;
+    this._entries.addAll(entries);
+    this._rightBracket = rightBracket;
+  }
+  accept(ASTVisitor visitor) => visitor.visitMapLiteral(this);
+  Token get beginToken {
+    Token token = modifier;
+    if (token != null) {
+      return token;
+    }
+    TypeArgumentList typeArguments7 = typeArguments;
+    if (typeArguments7 != null) {
+      return typeArguments7.beginToken;
+    }
+    return _leftBracket;
+  }
+  Token get endToken => _rightBracket;
+  /**
+   * Return the entries in the map.
+   * @return the entries in the map
+   */
+  NodeList<MapLiteralEntry> get entries => _entries;
+  /**
+   * Return the left curly bracket.
+   * @return the left curly bracket
+   */
+  Token get leftBracket => _leftBracket;
+  /**
+   * Return the right curly bracket.
+   * @return the right curly bracket
+   */
+  Token get rightBracket => _rightBracket;
+  /**
+   * Set the left curly bracket to the given token.
+   * @param bracket the left curly bracket
+   */
+  void set leftBracket7(Token bracket) {
+    _leftBracket = bracket;
+  }
+  /**
+   * Set the right curly bracket to the given token.
+   * @param bracket the right curly bracket
+   */
+  void set rightBracket7(Token bracket) {
+    _rightBracket = bracket;
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    _entries.accept(visitor);
+  }
+}
+/**
+ * Instances of the class {@code MapLiteralEntry} represent a single key/value pair in a map
+ * literal.
+ * <pre>
+ * mapLiteralEntry ::={@link StringLiteral key} ':' {@link Expression value}</pre>
+ */
+class MapLiteralEntry extends ASTNode {
+  /**
+   * The key with which the value will be associated.
+   */
+  StringLiteral _key;
+  /**
+   * The colon that separates the key from the value.
+   */
+  Token _separator;
+  /**
+   * The expression computing the value that will be associated with the key.
+   */
+  Expression _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._key = becomeParentOf(key);
+    this._separator = separator;
+    this._value = becomeParentOf(value);
+  }
+  accept(ASTVisitor visitor) => visitor.visitMapLiteralEntry(this);
+  Token get beginToken => _key.beginToken;
+  Token get endToken => _value.endToken;
+  /**
+   * Return the key with which the value will be associated.
+   * @return the key with which the value will be associated
+   */
+  StringLiteral get key => _key;
+  /**
+   * Return the colon that separates the key from the value.
+   * @return the colon that separates the key from the value
+   */
+  Token get separator => _separator;
+  /**
+   * Return the expression computing the value that will be associated with the key.
+   * @return the expression computing the value that will be associated with the key
+   */
+  Expression get value => _value;
+  /**
+   * 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) {
+    _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;
+  }
+  /**
+   * 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) {
+    _value = becomeParentOf(expression);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_key, visitor);
+    safelyVisitChild(_value, visitor);
+  }
+}
+/**
+ * Instances of the class {@code MethodDeclaration} represent a method declaration.
+ * <pre>
+ * methodDeclaration ::=
+ * methodSignature {@link FunctionBody body}methodSignature ::=
+ * 'external'? ('abstract' | 'static')? {@link Type returnType}? ('get' | 'set')? methodName{@link FormalParameterList formalParameterList}methodName ::={@link SimpleIdentifier name} ('.' {@link SimpleIdentifier name})?
+ * | 'operator' {@link SimpleIdentifier operator}</pre>
+ */
+class MethodDeclaration extends ClassMember {
+  /**
+   * The token for the 'external' keyword, or {@code null} if the constructor is not external.
+   */
+  Token _externalKeyword;
+  /**
+   * The token representing the 'abstract' or 'static' keyword, or {@code null} if neither modifier
+   * was specified.
+   */
+  Token _modifierKeyword;
+  /**
+   * The return type of the method, or {@code null} if no return type was declared.
+   */
+  TypeName _returnType;
+  /**
+   * The token representing the 'get' or 'set' keyword, or {@code null} if this is a method
+   * declaration rather than a property declaration.
+   */
+  Token _propertyKeyword;
+  /**
+   * The token representing the 'operator' keyword, or {@code null} if this method does not declare
+   * an operator.
+   */
+  Token _operatorKeyword;
+  /**
+   * The name of the method.
+   */
+  Identifier _name;
+  /**
+   * The parameters associated with the method, or {@code null} if this method declares a getter.
+   */
+  FormalParameterList _parameters;
+  /**
+   * The body of the method.
+   */
+  FunctionBody _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) : super(comment, metadata) {
+    this._externalKeyword = externalKeyword;
+    this._modifierKeyword = modifierKeyword;
+    this._returnType = becomeParentOf(returnType);
+    this._propertyKeyword = propertyKeyword;
+    this._operatorKeyword = operatorKeyword;
+    this._name = becomeParentOf(name);
+    this._parameters = becomeParentOf(parameters);
+    this._body = becomeParentOf(body);
+  }
+  accept(ASTVisitor visitor) => visitor.visitMethodDeclaration(this);
+  /**
+   * Return the body of the method.
+   * @return the body of the method
+   */
+  FunctionBody get body => _body;
+  /**
+   * Return the element associated with this method, or {@code null} if the AST structure has not
+   * been resolved. The element can either be a {@link MethodElement}, if this represents the
+   * declaration of a normal method, or a {@link PropertyAccessorElement} if this represents the
+   * 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;
+  Token get endToken => _body.endToken;
+  /**
+   * Return the token for the 'external' keyword, or {@code null} if the constructor is not
+   * external.
+   * @return the token for the 'external' keyword
+   */
+  Token get externalKeyword => _externalKeyword;
+  /**
+   * Return the token representing the 'abstract' or 'static' keyword, or {@code null} if neither
+   * modifier was specified.
+   * @return the token representing the 'abstract' or 'static' keyword
+   */
+  Token get modifierKeyword => _modifierKeyword;
+  /**
+   * Return the name of the method.
+   * @return the name of the method
+   */
+  Identifier get name => _name;
+  /**
+   * Return the token representing the 'operator' keyword, or {@code null} if this method does not
+   * declare an operator.
+   * @return the token representing the 'operator' keyword
+   */
+  Token get operatorKeyword => _operatorKeyword;
+  /**
+   * Return the parameters associated with the method, or {@code null} if this method declares a
+   * getter.
+   * @return the parameters associated with the method
+   */
+  FormalParameterList get parameters => _parameters;
+  /**
+   * Return the token representing the 'get' or 'set' keyword, or {@code null} if this is a method
+   * declaration rather than a property declaration.
+   * @return the token representing the 'get' or 'set' keyword
+   */
+  Token get propertyKeyword => _propertyKeyword;
+  /**
+   * Return the return type of the method, or {@code null} if no return type was declared.
+   * @return the return type of the method
+   */
+  TypeName get returnType => _returnType;
+  /**
+   * 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;
+  /**
+   * Return {@code true} if this method declares an operator.
+   * @return {@code true} if this method declares an operator
+   */
+  bool isOperator() => _operatorKeyword != null;
+  /**
+   * 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;
+  /**
+   * Set the body of the method to the given function body.
+   * @param functionBody the body of the method
+   */
+  void set body8(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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * Set the name of the method to the given identifier.
+   * @param identifier the name of the method
+   */
+  void set name10(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;
+  }
+  /**
+   * 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);
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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) {
+    _returnType = becomeParentOf(typeName);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_returnType, visitor);
+    safelyVisitChild(_name, visitor);
+    safelyVisitChild(_parameters, visitor);
+    safelyVisitChild(_body, visitor);
+  }
+  Token get firstTokenAfterCommentAndMetadata {
+    if (_modifierKeyword != null) {
+      return _modifierKeyword;
+    } else if (_returnType != null) {
+      return _returnType.beginToken;
+    } else if (_propertyKeyword != null) {
+      return _propertyKeyword;
+    } else if (_operatorKeyword != null) {
+      return _operatorKeyword;
+    }
+    return _name.beginToken;
+  }
+}
+/**
+ * Instances of the class {@code MethodInvocation} represent the invocation of either a function or
+ * a method. Invocations of functions resulting from evaluating an expression are represented by{@link FunctionExpressionInvocation function expression invocation} nodes. Invocations of getters
+ * and setters are represented by either {@link PrefixedIdentifier prefixed identifier} or{@link PropertyAccess property access} nodes.
+ * <pre>
+ * methodInvoction ::=
+ * ({@link Expression target} '.')? {@link SimpleIdentifier methodName} {@link ArgumentList argumentList}</pre>
+ */
+class MethodInvocation extends Expression {
+  /**
+   * The expression producing the object on which the method is defined, or {@code null} if there is
+   * no target (that is, the target is implicitly {@code this}).
+   */
+  Expression _target;
+  /**
+   * The period that separates the target from the method name, or {@code null} if there is no
+   * target.
+   */
+  Token _period;
+  /**
+   * The name of the method being invoked.
+   */
+  SimpleIdentifier _methodName;
+  /**
+   * The list of arguments to the method.
+   */
+  ArgumentList _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._target = becomeParentOf(target);
+    this._period = period;
+    this._methodName = becomeParentOf(methodName);
+    this._argumentList = becomeParentOf(argumentList);
+  }
+  accept(ASTVisitor visitor) => visitor.visitMethodInvocation(this);
+  /**
+   * Return the list of arguments to the method.
+   * @return the list of arguments to the method
+   */
+  ArgumentList get argumentList => _argumentList;
+  Token get beginToken {
+    if (_target != null) {
+      return _target.beginToken;
+    }
+    return _methodName.beginToken;
+  }
+  Token get endToken => _argumentList.endToken;
+  /**
+   * Return the name of the method being invoked.
+   * @return the name of the method being invoked
+   */
+  SimpleIdentifier get methodName => _methodName;
+  /**
+   * Return the period that separates the target from the method name, or {@code null} if there is
+   * no target.
+   * @return the period that separates the target from the method name
+   */
+  Token get period => _period;
+  /**
+   * Return the expression used to compute the receiver of the invocation. If this invocation is not
+   * part of a cascade expression, then this is the same as {@link #getTarget()}. If this invocation
+   * is part of a cascade expression, then the target stored with the cascade expression is
+   * returned.
+   * @return the expression used to compute the receiver of the invocation
+   * @see #getTarget()
+   */
+  Expression get realTarget {
+    if (isCascaded()) {
+      ASTNode ancestor = parent;
+      while (ancestor is! CascadeExpression) {
+        if (ancestor == null) {
+          return _target;
+        }
+        ancestor = ancestor.parent;
+      }
+      return (ancestor as CascadeExpression).target;
+    }
+    return _target;
+  }
+  /**
+   * Return the expression producing the object on which the method is defined, or {@code null} if
+   * there is no target (that is, the target is implicitly {@code this}) or if this method
+   * invocation is part of a cascade expression.
+   * @return the expression producing the object on which the method is defined
+   * @see #getRealTarget()
+   */
+  Expression get target => _target;
+  /**
+   * Return {@code true} if this expression is cascaded. If it is, then the target of this
+   * 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;
+  /**
+   * 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);
+  }
+  /**
+   * 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) {
+    _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;
+  }
+  /**
+   * 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) {
+    _target = becomeParentOf(expression);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_target, visitor);
+    safelyVisitChild(_methodName, visitor);
+    safelyVisitChild(_argumentList, visitor);
+  }
+}
+/**
+ * Instances of the class {@code NamedExpression} represent an expression that has a name associated
+ * with it. They are used in method invocations when there are named parameters.
+ * <pre>
+ * namedExpression ::={@link Label name} {@link Expression expression}</pre>
+ */
+class NamedExpression extends Expression {
+  /**
+   * The name associated with the expression.
+   */
+  Label _name;
+  /**
+   * The expression with which the name is associated.
+   */
+  Expression _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._name = becomeParentOf(name);
+    this._expression = becomeParentOf(expression);
+  }
+  accept(ASTVisitor visitor) => visitor.visitNamedExpression(this);
+  Token get beginToken => _name.beginToken;
+  Token get endToken => _expression.endToken;
+  /**
+   * Return the expression with which the name is associated.
+   * @return the expression with which the name is associated
+   */
+  Expression get expression => _expression;
+  /**
+   * Return the name associated with the expression.
+   * @return the name associated with the expression
+   */
+  Label get name => _name;
+  /**
+   * 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);
+  }
+  /**
+   * Set the name associated with the expression to the given identifier.
+   * @param identifier the name associated with the expression
+   */
+  void set name11(Label identifier) {
+    _name = becomeParentOf(identifier);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_name, visitor);
+    safelyVisitChild(_expression, visitor);
+  }
+}
+/**
+ * The abstract class {@code NamespaceDirective} defines the behavior common to nodes that represent
+ * a directive that impacts the namespace of a library.
+ * <pre>
+ * directive ::={@link ExportDirective exportDirective}| {@link ImportDirective importDirective}</pre>
+ */
+abstract class NamespaceDirective extends Directive {
+  /**
+   * 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;
+  /**
+   * The semicolon terminating the directive.
+   */
+  Token _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) : super(comment, metadata) {
+    this._combinators = new NodeList<Combinator>(this);
+    this._keyword = keyword;
+    this._libraryUri = becomeParentOf(libraryUri);
+    this._combinators.addAll(combinators);
+    this._semicolon = 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
+   */
+  NodeList<Combinator> get combinators => _combinators;
+  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
+   */
+  Token get semicolon => _semicolon;
+  /**
+   * 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) {
+    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;
+  }
+  Token get firstTokenAfterCommentAndMetadata => _keyword;
+}
+/**
+ * The abstract class {@code NormalFormalParameter} defines the behavior common to formal parameters
+ * that are required (are not optional).
+ * <pre>
+ * normalFormalParameter ::={@link FunctionTypedFormalParameter functionSignature}| {@link FieldFormalParameter fieldFormalParameter}| {@link SimpleFormalParameter simpleFormalParameter}</pre>
+ */
+abstract class NormalFormalParameter extends FormalParameter {
+  /**
+   * The documentation comment associated with this parameter, or {@code null} if this parameter
+   * does not have a documentation comment associated with it.
+   */
+  Comment _comment;
+  /**
+   * The annotations associated with this parameter.
+   */
+  NodeList<Annotation> _metadata;
+  /**
+   * The name of the parameter being declared.
+   */
+  SimpleIdentifier _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._metadata = new NodeList<Annotation>(this);
+    this._comment = becomeParentOf(comment);
+    this._metadata.addAll(metadata);
+    this._identifier = becomeParentOf(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
+   */
+  Comment get documentationComment => _comment;
+  SimpleIdentifier get identifier => _identifier;
+  ParameterKind get kind {
+    ASTNode parent6 = parent;
+    if (parent6 is DefaultFormalParameter) {
+      return (parent6 as DefaultFormalParameter).kind;
+    }
+    return ParameterKind.REQUIRED;
+  }
+  /**
+   * Return the annotations associated with this parameter.
+   * @return the annotations associated with this parameter
+   */
+  NodeList<Annotation> get metadata => _metadata;
+  /**
+   * Return {@code true} if this parameter is a const parameter.
+   * @return {@code true} if this parameter is a const parameter
+   */
+  bool isConst();
+  /**
+   * Return {@code true} if this parameter is a final parameter.
+   * @return {@code true} if this parameter is a final parameter
+   */
+  bool isFinal();
+  /**
+   * 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);
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    if (commentIsBeforeAnnotations()) {
+      safelyVisitChild(_comment, visitor);
+      _metadata.accept(visitor);
+    } else {
+      for (ASTNode child in sortedCommentAndAnnotations) {
+        child.accept(visitor);
+      }
+    }
+  }
+  /**
+   * Return {@code true} if the comment is lexically before any annotations.
+   * @return {@code true} if the comment is lexically before any annotations
+   */
+  bool commentIsBeforeAnnotations() {
+    if (_comment == null || _metadata.isEmpty) {
+      return true;
+    }
+    Annotation firstAnnotation = _metadata[0];
+    return _comment.offset < firstAnnotation.offset;
+  }
+  /**
+   * Return an array containing the comment and annotations associated with this parameter, sorted
+   * in lexical order.
+   * @return the comment and annotations associated with this parameter in the order in which they
+   * appeared in the original source
+   */
+  List<ASTNode> get sortedCommentAndAnnotations {
+    List<ASTNode> childList = new List<ASTNode>();
+    childList.add(_comment);
+    childList.addAll(_metadata);
+    List<ASTNode> children = new List.from(childList);
+    children.sort();
+    return children;
+  }
+}
+/**
+ * Instances of the class {@code NullLiteral} represent a null literal expression.
+ * <pre>
+ * nullLiteral ::=
+ * 'null'
+ * </pre>
+ */
+class NullLiteral extends Literal {
+  /**
+   * The token representing the literal.
+   */
+  Token _literal;
+  /**
+   * Initialize a newly created null literal.
+   * @param token the token representing the literal
+   */
+  NullLiteral(Token token) {
+    this._literal = token;
+  }
+  accept(ASTVisitor visitor) => visitor.visitNullLiteral(this);
+  Token get beginToken => _literal;
+  Token get endToken => _literal;
+  /**
+   * Return the token representing the literal.
+   * @return the token representing the literal
+   */
+  Token get literal => _literal;
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+  }
+}
+/**
+ * Instances of the class {@code ParenthesizedExpression} represent a parenthesized expression.
+ * <pre>
+ * parenthesizedExpression ::=
+ * '(' {@link Expression expression} ')'
+ * </pre>
+ */
+class ParenthesizedExpression extends Expression {
+  /**
+   * The left parenthesis.
+   */
+  Token _leftParenthesis;
+  /**
+   * The expression within the parentheses.
+   */
+  Expression _expression;
+  /**
+   * The right parenthesis.
+   */
+  Token _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._leftParenthesis = leftParenthesis;
+    this._expression = becomeParentOf(expression);
+    this._rightParenthesis = rightParenthesis;
+  }
+  accept(ASTVisitor visitor) => visitor.visitParenthesizedExpression(this);
+  Token get beginToken => _leftParenthesis;
+  Token get endToken => _rightParenthesis;
+  /**
+   * Return the expression within the parentheses.
+   * @return the expression within the parentheses
+   */
+  Expression get expression => _expression;
+  /**
+   * Return the left parenthesis.
+   * @return the left parenthesis
+   */
+  Token get leftParenthesis => _leftParenthesis;
+  /**
+   * Return the right parenthesis.
+   * @return the right parenthesis
+   */
+  Token get rightParenthesis => _rightParenthesis;
+  /**
+   * 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);
+  }
+  /**
+   * Set the left parenthesis to the given token.
+   * @param parenthesis the left parenthesis
+   */
+  void set leftParenthesis10(Token parenthesis) {
+    _leftParenthesis = parenthesis;
+  }
+  /**
+   * Set the right parenthesis to the given token.
+   * @param parenthesis the right parenthesis
+   */
+  void set rightParenthesis10(Token parenthesis) {
+    _rightParenthesis = parenthesis;
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_expression, visitor);
+  }
+}
+/**
+ * Instances of the class {@code PartDirective} represent a part directive.
+ * <pre>
+ * partDirective ::={@link Annotation metadata} 'part' {@link StringLiteral partUri} ';'
+ * </pre>
+ */
+class PartDirective extends Directive {
+  /**
+   * The token representing the 'part' token.
+   */
+  Token _partToken;
+  /**
+   * The URI of the part being included.
+   */
+  StringLiteral _partUri;
+  /**
+   * The semicolon terminating the directive.
+   */
+  Token _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) : super(comment, metadata) {
+    this._partToken = partToken;
+    this._partUri = becomeParentOf(partUri);
+    this._semicolon = semicolon;
+  }
+  accept(ASTVisitor visitor) => visitor.visitPartDirective(this);
+  Token get endToken => _semicolon;
+  Token get keyword => _partToken;
+  /**
+   * Return the token representing the 'part' token.
+   * @return the token representing the 'part' token
+   */
+  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
+   */
+  Token get semicolon => _semicolon;
+  /**
+   * 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);
+  }
+  /**
+   * 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);
+  }
+  Token get firstTokenAfterCommentAndMetadata => _partToken;
+}
+/**
+ * Instances of the class {@code PartOfDirective} represent a part-of directive.
+ * <pre>
+ * partOfDirective ::={@link Annotation metadata} 'part' 'of' {@link Identifier libraryName} ';'
+ * </pre>
+ */
+class PartOfDirective extends Directive {
+  /**
+   * The token representing the 'part' token.
+   */
+  Token _partToken;
+  /**
+   * The token representing the 'of' token.
+   */
+  Token _ofToken;
+  /**
+   * The name of the library that the containing compilation unit is part of.
+   */
+  LibraryIdentifier _libraryName;
+  /**
+   * The semicolon terminating the directive.
+   */
+  Token _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) : super(comment, metadata) {
+    this._partToken = partToken;
+    this._ofToken = ofToken;
+    this._libraryName = becomeParentOf(libraryName);
+    this._semicolon = semicolon;
+  }
+  accept(ASTVisitor visitor) => visitor.visitPartOfDirective(this);
+  Token get endToken => _semicolon;
+  Token get keyword => _partToken;
+  /**
+   * Return the name of the library that the containing compilation unit is part of.
+   * @return the name of the library that the containing compilation unit is part of
+   */
+  LibraryIdentifier get libraryName => _libraryName;
+  /**
+   * Return the token representing the 'of' token.
+   * @return the token representing the 'of' token
+   */
+  Token get ofToken => _ofToken;
+  /**
+   * Return the token representing the 'part' token.
+   * @return the token representing the 'part' token
+   */
+  Token get partToken => _partToken;
+  /**
+   * Return the semicolon terminating the directive.
+   * @return the semicolon terminating the directive
+   */
+  Token get semicolon => _semicolon;
+  /**
+   * 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);
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_libraryName, visitor);
+  }
+  Token get firstTokenAfterCommentAndMetadata => _partToken;
+}
+/**
+ * Instances of the class {@code PostfixExpression} represent a postfix unary expression.
+ * <pre>
+ * postfixExpression ::={@link Expression operand} {@link Token operator}</pre>
+ */
+class PostfixExpression extends Expression {
+  /**
+   * The expression computing the operand for the operator.
+   */
+  Expression _operand;
+  /**
+   * The postfix operator being applied to the operand.
+   */
+  Token _operator;
+  /**
+   * The element associated with this the operator, or {@code null} if the AST structure has not
+   * been resolved, if the operator is not user definable, or if the operator could not be resolved.
+   */
+  MethodElement _element;
+  /**
+   * 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._operand = becomeParentOf(operand);
+    this._operator = operator;
+  }
+  accept(ASTVisitor visitor) => visitor.visitPostfixExpression(this);
+  Token get beginToken => _operand.beginToken;
+  /**
+   * Return the element associated with the operator, or {@code null} if the AST structure has not
+   * been resolved, if the operator is not user definable, or if the operator could not be resolved.
+   * One example of the latter case is an operator that is not defined for the type of the operand.
+   * @return the element associated with the operator
+   */
+  MethodElement get element => _element;
+  Token get endToken => _operator;
+  /**
+   * Return the expression computing the operand for the operator.
+   * @return the expression computing the operand for the operator
+   */
+  Expression get operand => _operand;
+  /**
+   * Return the postfix operator being applied to the operand.
+   * @return the postfix operator being applied to the operand
+   */
+  Token get operator => _operator;
+  /**
+   * 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;
+  }
+  /**
+   * 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) {
+    _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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_operand, visitor);
+  }
+}
+/**
+ * Instances of the class {@code PrefixExpression} represent a prefix unary expression.
+ * <pre>
+ * prefixExpression ::={@link Token operator} {@link Expression operand}</pre>
+ */
+class PrefixExpression extends Expression {
+  /**
+   * The prefix operator being applied to the operand.
+   */
+  Token _operator;
+  /**
+   * The expression computing the operand for the operator.
+   */
+  Expression _operand;
+  /**
+   * The element associated with the operator, or {@code null} if the AST structure has not been
+   * resolved, if the operator is not user definable, or if the operator could not be resolved.
+   */
+  MethodElement _element;
+  /**
+   * 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._operator = operator;
+    this._operand = becomeParentOf(operand);
+  }
+  accept(ASTVisitor visitor) => visitor.visitPrefixExpression(this);
+  Token get beginToken => _operator;
+  /**
+   * Return the element associated with the operator, or {@code null} if the AST structure has not
+   * been resolved, if the operator is not user definable, or if the operator could not be resolved.
+   * One example of the latter case is an operator that is not defined for the type of the operand.
+   * @return the element associated with the operator
+   */
+  MethodElement get element => _element;
+  Token get endToken => _operand.endToken;
+  /**
+   * Return the expression computing the operand for the operator.
+   * @return the expression computing the operand for the operator
+   */
+  Expression get operand => _operand;
+  /**
+   * Return the prefix operator being applied to the operand.
+   * @return the prefix operator being applied to the operand
+   */
+  Token get operator => _operator;
+  /**
+   * 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;
+  }
+  /**
+   * 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) {
+    _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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_operand, visitor);
+  }
+}
+/**
+ * Instances of the class {@code PrefixedIdentifier} represent either an identifier that is prefixed
+ * or an access to an object property where the target of the property access is a simple
+ * identifier.
+ * <pre>
+ * prefixedIdentifier ::={@link SimpleIdentifier prefix} '.' {@link SimpleIdentifier identifier}</pre>
+ */
+class PrefixedIdentifier extends Identifier {
+  /**
+   * The prefix associated with the library in which the identifier is defined.
+   */
+  SimpleIdentifier _prefix;
+  /**
+   * The period used to separate the prefix from the identifier.
+   */
+  Token _period;
+  /**
+   * The identifier being prefixed.
+   */
+  SimpleIdentifier _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._prefix = becomeParentOf(prefix);
+    this._period = period;
+    this._identifier = becomeParentOf(identifier);
+  }
+  accept(ASTVisitor visitor) => visitor.visitPrefixedIdentifier(this);
+  Token get beginToken => _prefix.beginToken;
+  Token get endToken => _identifier.endToken;
+  /**
+   * Return the identifier being prefixed.
+   * @return the identifier being prefixed
+   */
+  SimpleIdentifier get identifier => _identifier;
+  String get name => "${_prefix.name}.${_identifier.name}";
+  /**
+   * Return the period used to separate the prefix from the identifier.
+   * @return the period used to separate the prefix from the identifier
+   */
+  Token get period => _period;
+  /**
+   * Return the prefix associated with the library in which the identifier is defined.
+   * @return the prefix associated with the library in which the identifier is defined
+   */
+  SimpleIdentifier get prefix => _prefix;
+  /**
+   * Set the identifier being prefixed to the given identifier.
+   * @param identifier the identifier being prefixed
+   */
+  void set identifier5(SimpleIdentifier identifier) {
+    this._identifier = becomeParentOf(identifier);
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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) {
+    _prefix = becomeParentOf(identifier);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_prefix, visitor);
+    safelyVisitChild(_identifier, visitor);
+  }
+}
+/**
+ * Instances of the class {@code PropertyAccess} represent the access of a property of an object.
+ * <p>
+ * Note, however, that accesses to properties of objects can also be represented as{@link PrefixedIdentifier prefixed identifier} nodes in cases where the target is also a simple
+ * identifier.
+ * <pre>
+ * propertyAccess ::={@link Expression target} '.' {@link SimpleIdentifier propertyName}</pre>
+ */
+class PropertyAccess extends Expression {
+  /**
+   * The expression computing the object defining the property being accessed.
+   */
+  Expression _target;
+  /**
+   * The property access operator.
+   */
+  Token _operator;
+  /**
+   * The name of the property being accessed.
+   */
+  SimpleIdentifier _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._target = becomeParentOf(target);
+    this._operator = operator;
+    this._propertyName = becomeParentOf(propertyName);
+  }
+  accept(ASTVisitor visitor) => visitor.visitPropertyAccess(this);
+  Token get beginToken {
+    if (_target != null) {
+      return _target.beginToken;
+    }
+    return _operator;
+  }
+  Token get endToken => _propertyName.endToken;
+  /**
+   * Return the property access operator.
+   * @return the property access operator
+   */
+  Token get operator => _operator;
+  /**
+   * Return the name of the property being accessed.
+   * @return the name of the property being accessed
+   */
+  SimpleIdentifier get propertyName => _propertyName;
+  /**
+   * Return the expression used to compute the receiver of the invocation. If this invocation is not
+   * part of a cascade expression, then this is the same as {@link #getTarget()}. If this invocation
+   * is part of a cascade expression, then the target stored with the cascade expression is
+   * returned.
+   * @return the expression used to compute the receiver of the invocation
+   * @see #getTarget()
+   */
+  Expression get realTarget {
+    if (isCascaded()) {
+      ASTNode ancestor = parent;
+      while (ancestor is! CascadeExpression) {
+        if (ancestor == null) {
+          return _target;
+        }
+        ancestor = ancestor.parent;
+      }
+      return (ancestor as CascadeExpression).target;
+    }
+    return _target;
+  }
+  /**
+   * Return the expression computing the object defining the property being accessed, or{@code null} if this property access is part of a cascade expression.
+   * @return the expression computing the object defining the property being accessed
+   * @see #getRealTarget()
+   */
+  Expression get target => _target;
+  bool isAssignable() => true;
+  /**
+   * Return {@code true} if this expression is cascaded. If it is, then the target of this
+   * 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;
+  /**
+   * Set the property access operator to the given token.
+   * @param operator the property access operator
+   */
+  void set operator6(Token operator) {
+    this._operator = operator;
+  }
+  /**
+   * 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) {
+    _propertyName = becomeParentOf(identifier);
+  }
+  /**
+   * Set the expression computing the object defining the property being accessed to the given
+   * expression.
+   * @param expression the expression computing the object defining the property being accessed
+   */
+  void set target4(Expression expression) {
+    _target = becomeParentOf(expression);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_target, visitor);
+    safelyVisitChild(_propertyName, visitor);
+  }
+}
+/**
+ * Instances of the class {@code RedirectingConstructorInvocation} represent the invocation of a
+ * another constructor in the same class from within a constructor's initialization list.
+ * <pre>
+ * redirectingConstructorInvocation ::=
+ * 'this' ('.' identifier)? arguments
+ * </pre>
+ */
+class RedirectingConstructorInvocation extends ConstructorInitializer {
+  /**
+   * The token for the 'this' keyword.
+   */
+  Token _keyword;
+  /**
+   * The token for the period before the name of the constructor that is being invoked, or{@code null} if the unnamed constructor is being invoked.
+   */
+  Token _period;
+  /**
+   * The name of the constructor that is being invoked, or {@code null} if the unnamed constructor
+   * is being invoked.
+   */
+  SimpleIdentifier _constructorName;
+  /**
+   * The list of arguments to the constructor.
+   */
+  ArgumentList _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._keyword = keyword;
+    this._period = period;
+    this._constructorName = becomeParentOf(constructorName);
+    this._argumentList = becomeParentOf(argumentList);
+  }
+  accept(ASTVisitor visitor) => visitor.visitRedirectingConstructorInvocation(this);
+  /**
+   * Return the list of arguments to the constructor.
+   * @return the list of arguments to the constructor
+   */
+  ArgumentList get argumentList => _argumentList;
+  Token get beginToken => _keyword;
+  /**
+   * Return the name of the constructor that is being invoked, or {@code null} if the unnamed
+   * constructor is being invoked.
+   * @return the name of the constructor that is being invoked
+   */
+  SimpleIdentifier get constructorName => _constructorName;
+  Token get endToken => _argumentList.endToken;
+  /**
+   * Return the token for the 'this' keyword.
+   * @return the token for the 'this' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * Return the token for the period before the name of the constructor that is being invoked, or{@code null} if the unnamed constructor is being invoked.
+   * @return the token for the period before the name of the constructor that is being invoked
+   */
+  Token get period => _period;
+  /**
+   * 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);
+  }
+  /**
+   * 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) {
+    _constructorName = becomeParentOf(identifier);
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_constructorName, visitor);
+    safelyVisitChild(_argumentList, visitor);
+  }
+}
+/**
+ * Instances of the class {@code ReturnStatement} represent a return statement.
+ * <pre>
+ * returnStatement ::=
+ * 'return' {@link Expression expression}? ';'
+ * </pre>
+ */
+class ReturnStatement extends Statement {
+  /**
+   * The token representing the 'return' keyword.
+   */
+  Token _keyword;
+  /**
+   * The expression computing the value to be returned, or {@code null} if no explicit value was
+   * provided.
+   */
+  Expression _expression;
+  /**
+   * The semicolon terminating the statement.
+   */
+  Token _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._keyword = keyword;
+    this._expression = becomeParentOf(expression);
+    this._semicolon = semicolon;
+  }
+  accept(ASTVisitor visitor) => visitor.visitReturnStatement(this);
+  Token get beginToken => _keyword;
+  Token get endToken => _semicolon;
+  /**
+   * Return the expression computing the value to be returned, or {@code null} if no explicit value
+   * was provided.
+   * @return the expression computing the value to be returned
+   */
+  Expression get expression => _expression;
+  /**
+   * Return the token representing the 'return' keyword.
+   * @return the token representing the 'return' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * Return the semicolon terminating the statement.
+   * @return the semicolon terminating the statement
+   */
+  Token get semicolon => _semicolon;
+  /**
+   * 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);
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_expression, visitor);
+  }
+}
+/**
+ * Instances of the class {@code ScriptTag} represent the script tag that can optionally occur at
+ * the beginning of a compilation unit.
+ * <pre>
+ * scriptTag ::=
+ * '#!' (~NEWLINE)* NEWLINE
+ * </pre>
+ */
+class ScriptTag extends ASTNode {
+  /**
+   * The token representing this script tag.
+   */
+  Token _scriptTag;
+  /**
+   * Initialize a newly created script tag.
+   * @param scriptTag the token representing this script tag
+   */
+  ScriptTag(Token scriptTag) {
+    this._scriptTag = scriptTag;
+  }
+  accept(ASTVisitor visitor) => visitor.visitScriptTag(this);
+  Token get beginToken => _scriptTag;
+  Token get endToken => _scriptTag;
+  /**
+   * Return the token representing this script tag.
+   * @return the token representing this script tag
+   */
+  Token get scriptTag => _scriptTag;
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+  }
+}
+/**
+ * Instances of the class {@code ShowCombinator} represent a combinator that restricts the names
+ * being imported to those in a given list.
+ * <pre>
+ * showCombinator ::=
+ * 'show' {@link SimpleIdentifier identifier} (',' {@link SimpleIdentifier identifier})
+ * </pre>
+ */
+class ShowCombinator extends Combinator {
+  /**
+   * The list of names from the library that are made visible by this combinator.
+   */
+  NodeList<SimpleIdentifier> _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) : super(keyword) {
+    this._shownNames = new NodeList<SimpleIdentifier>(this);
+    this._shownNames.addAll(shownNames);
+  }
+  accept(ASTVisitor visitor) => visitor.visitShowCombinator(this);
+  Token get endToken => _shownNames.endToken;
+  /**
+   * Return the list of names from the library that are made visible by this combinator.
+   * @return the list of names from the library that are made visible by this combinator
+   */
+  NodeList<SimpleIdentifier> get shownNames => _shownNames;
+  void visitChildren(ASTVisitor<Object> visitor) {
+    _shownNames.accept(visitor);
+  }
+}
+/**
+ * Instances of the class {@code SimpleFormalParameter} represent a simple formal parameter.
+ * <pre>
+ * simpleFormalParameter ::=
+ * ('final' {@link TypeName type} | 'var' | {@link TypeName type})? {@link SimpleIdentifier identifier}</pre>
+ */
+class SimpleFormalParameter extends NormalFormalParameter {
+  /**
+   * The token representing either the 'final', 'const' or 'var' keyword, or {@code null} if no
+   * keyword was used.
+   */
+  Token _keyword;
+  /**
+   * The name of the declared type of the parameter, or {@code null} if the parameter does not have
+   * a declared type.
+   */
+  TypeName _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) : super(comment, metadata, identifier) {
+    this._keyword = keyword;
+    this._type = becomeParentOf(type);
+  }
+  accept(ASTVisitor visitor) => visitor.visitSimpleFormalParameter(this);
+  Token get beginToken {
+    if (_keyword != null) {
+      return _keyword;
+    } else if (_type != null) {
+      return _type.beginToken;
+    }
+    return identifier.beginToken;
+  }
+  Token get endToken => identifier.endToken;
+  /**
+   * Return the token representing either the 'final', 'const' or 'var' keyword.
+   * @return the token representing either the 'final', 'const' or 'var' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * Return the name of the declared type of the parameter, or {@code null} if the parameter does
+   * not have a declared type.
+   * @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;
+  /**
+   * 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;
+  }
+  /**
+   * 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) {
+    _type = becomeParentOf(typeName);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_type, visitor);
+    safelyVisitChild(identifier, visitor);
+  }
+}
+/**
+ * Instances of the class {@code SimpleIdentifier} represent a simple identifier.
+ * <pre>
+ * simpleIdentifier ::=
+ * initialCharacter internalCharacter
+ * initialCharacter ::= '_' | '$' | letter
+ * internalCharacter ::= '_' | '$' | letter | digit
+ * </pre>
+ */
+class SimpleIdentifier extends Identifier {
+  /**
+   * The token representing the identifier.
+   */
+  Token _token;
+  /**
+   * Initialize a newly created identifier.
+   * @param token the token representing the identifier
+   */
+  SimpleIdentifier(Token token) {
+    this._token = token;
+  }
+  accept(ASTVisitor visitor) => visitor.visitSimpleIdentifier(this);
+  Token get beginToken => _token;
+  Token get endToken => _token;
+  String get name => _token.lexeme;
+  /**
+   * Return the token representing the identifier.
+   * @return the token representing the identifier
+   */
+  Token get token => _token;
+  /**
+   * Return {@code true} if this expression is computing a right-hand value.
+   * <p>
+   * Note that {@link #inGetterContext()} and {@link #inSetterContext()} are not opposites, nor are
+   * they mutually exclusive. In other words, it is possible for both methods to return {@code true}when invoked on the same node.
+   * @return {@code true} if this expression is in a context where a getter will be invoked
+   */
+  bool inGetterContext() {
+    ASTNode parent7 = parent;
+    ASTNode target = this;
+    if (parent7 is PrefixedIdentifier) {
+      PrefixedIdentifier prefixed = parent7 as PrefixedIdentifier;
+      if (prefixed.identifier != this) {
+        return false;
+      }
+      parent7 = prefixed.parent;
+      target = prefixed;
+    }
+    if (parent7 is AssignmentExpression) {
+      AssignmentExpression expr = parent7 as AssignmentExpression;
+      if (expr.leftHandSide == target && expr.operator.type == TokenType.EQ) {
+        return false;
+      }
+    }
+    return true;
+  }
+  /**
+   * Return {@code true} if this expression is computing a left-hand value.
+   * <p>
+   * Note that {@link #inGetterContext()} and {@link #inSetterContext()} are not opposites, nor are
+   * they mutually exclusive. In other words, it is possible for both methods to return {@code true}when invoked on the same node.
+   * @return {@code true} if this expression is in a context where a setter will be invoked
+   */
+  bool inSetterContext() {
+    ASTNode parent8 = parent;
+    ASTNode target = this;
+    if (parent8 is PrefixedIdentifier) {
+      PrefixedIdentifier prefixed = parent8 as PrefixedIdentifier;
+      if (prefixed.identifier != this) {
+        return false;
+      }
+      parent8 = prefixed.parent;
+      target = prefixed;
+    }
+    if (parent8 is PrefixExpression) {
+      return (parent8 as PrefixExpression).operator.type.isIncrementOperator();
+    } else if (parent8 is PostfixExpression) {
+      return true;
+    } else if (parent8 is AssignmentExpression) {
+      return (parent8 as AssignmentExpression).leftHandSide == target;
+    }
+    return false;
+  }
+  bool isSynthetic() => _token.isSynthetic();
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+  }
+}
+/**
+ * Instances of the class {@code SimpleStringLiteral} represent a string literal expression that
+ * does not contain any interpolations.
+ * <pre>
+ * simpleStringLiteral ::=
+ * rawStringLiteral
+ * | basicStringLiteral
+ * rawStringLiteral ::=
+ * '@' basicStringLiteral
+ * simpleStringLiteral ::=
+ * multiLineStringLiteral
+ * | singleLineStringLiteral
+ * multiLineStringLiteral ::=
+ * "'''" characters "'''"
+ * | '"""' characters '"""'
+ * singleLineStringLiteral ::=
+ * "'" characters "'"
+ * '"' characters '"'
+ * </pre>
+ */
+class SimpleStringLiteral extends StringLiteral {
+  /**
+   * The token representing the literal.
+   */
+  Token _literal;
+  /**
+   * The value of the literal.
+   */
+  String _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._literal = literal;
+    this._value = value;
+  }
+  accept(ASTVisitor visitor) => visitor.visitSimpleStringLiteral(this);
+  Token get beginToken => _literal;
+  Token get endToken => _literal;
+  /**
+   * Return the token representing the literal.
+   * @return the token representing the literal
+   */
+  Token get literal => _literal;
+  /**
+   * Return the value of the literal.
+   * @return the value of the literal
+   */
+  String get value => _value;
+  /**
+   * Return {@code true} if this string literal is a multi-line string.
+   * @return {@code true} if this string literal is a multi-line string
+   */
+  bool isMultiline() {
+    if (_value.length < 6) {
+      return false;
+    }
+    return _value.endsWith("\"\"\"") || _value.endsWith("'''");
+  }
+  /**
+   * 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 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;
+  }
+  /**
+   * Set the value of the literal to the given string.
+   * @param string the value of the literal
+   */
+  void set value9(String string) {
+    _value = string;
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+  }
+}
+/**
+ * Instances of the class {@code Statement} defines the behavior common to nodes that represent a
+ * statement.
+ * <pre>
+ * statement ::={@link Block block}| {@link VariableDeclarationStatement initializedVariableDeclaration ';'}| {@link ForStatement forStatement}| {@link ForEachStatement forEachStatement}| {@link WhileStatement whileStatement}| {@link DoStatement doStatement}| {@link SwitchStatement switchStatement}| {@link IfStatement ifStatement}| {@link TryStatement tryStatement}| {@link BreakStatement breakStatement}| {@link ContinueStatement continueStatement}| {@link ReturnStatement returnStatement}| {@link ExpressionStatement expressionStatement}| {@link FunctionDeclarationStatement functionSignature functionBody}</pre>
+ */
+abstract class Statement extends ASTNode {
+}
+/**
+ * Instances of the class {@code StringInterpolation} represent a string interpolation literal.
+ * <pre>
+ * stringInterpolation ::=
+ * ''' {@link InterpolationElement interpolationElement}* '''
+ * | '"' {@link InterpolationElement interpolationElement}* '"'
+ * </pre>
+ */
+class StringInterpolation extends StringLiteral {
+  /**
+   * The elements that will be composed to produce the resulting string.
+   */
+  NodeList<InterpolationElement> _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._elements = new NodeList<InterpolationElement>(this);
+    this._elements.addAll(elements);
+  }
+  accept(ASTVisitor visitor) => visitor.visitStringInterpolation(this);
+  Token get beginToken => _elements.beginToken;
+  /**
+   * Return the elements that will be composed to produce the resulting string.
+   * @return the elements that will be composed to produce the resulting string
+   */
+  NodeList<InterpolationElement> get elements => _elements;
+  Token get endToken => _elements.endToken;
+  void visitChildren(ASTVisitor<Object> visitor) {
+    _elements.accept(visitor);
+  }
+}
+/**
+ * Instances of the class {@code StringLiteral} represent a string literal expression.
+ * <pre>
+ * stringLiteral ::={@link SimpleStringLiteral simpleStringLiteral}| {@link AdjacentStrings adjacentStrings}| {@link StringInterpolation stringInterpolation}</pre>
+ */
+abstract class StringLiteral extends Literal {
+}
+/**
+ * Instances of the class {@code SuperConstructorInvocation} represent the invocation of a
+ * superclass' constructor from within a constructor's initialization list.
+ * <pre>
+ * superInvocation ::=
+ * 'super' ('.' {@link SimpleIdentifier name})? {@link ArgumentList argumentList}</pre>
+ */
+class SuperConstructorInvocation extends ConstructorInitializer {
+  /**
+   * The token for the 'super' keyword.
+   */
+  Token _keyword;
+  /**
+   * The token for the period before the name of the constructor that is being invoked, or{@code null} if the unnamed constructor is being invoked.
+   */
+  Token _period;
+  /**
+   * The name of the constructor that is being invoked, or {@code null} if the unnamed constructor
+   * is being invoked.
+   */
+  SimpleIdentifier _constructorName;
+  /**
+   * The list of arguments to the constructor.
+   */
+  ArgumentList _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._keyword = keyword;
+    this._period = period;
+    this._constructorName = becomeParentOf(constructorName);
+    this._argumentList = becomeParentOf(argumentList);
+  }
+  accept(ASTVisitor visitor) => visitor.visitSuperConstructorInvocation(this);
+  /**
+   * Return the list of arguments to the constructor.
+   * @return the list of arguments to the constructor
+   */
+  ArgumentList get argumentList => _argumentList;
+  Token get beginToken => _keyword;
+  /**
+   * Return the name of the constructor that is being invoked, or {@code null} if the unnamed
+   * constructor is being invoked.
+   * @return the name of the constructor that is being invoked
+   */
+  SimpleIdentifier get constructorName => _constructorName;
+  Token get endToken => _argumentList.endToken;
+  /**
+   * Return the token for the 'super' keyword.
+   * @return the token for the 'super' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * Return the token for the period before the name of the constructor that is being invoked, or{@code null} if the unnamed constructor is being invoked.
+   * @return the token for the period before the name of the constructor that is being invoked
+   */
+  Token get period => _period;
+  /**
+   * 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);
+  }
+  /**
+   * 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) {
+    _constructorName = becomeParentOf(identifier);
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_constructorName, visitor);
+    safelyVisitChild(_argumentList, visitor);
+  }
+}
+/**
+ * Instances of the class {@code SuperExpression} represent a super expression.
+ * <pre>
+ * superExpression ::=
+ * 'super'
+ * </pre>
+ */
+class SuperExpression extends Expression {
+  /**
+   * The token representing the keyword.
+   */
+  Token _keyword;
+  /**
+   * Initialize a newly created super expression.
+   * @param keyword the token representing the keyword
+   */
+  SuperExpression(Token keyword) {
+    this._keyword = keyword;
+  }
+  accept(ASTVisitor visitor) => visitor.visitSuperExpression(this);
+  Token get beginToken => _keyword;
+  Token get endToken => _keyword;
+  /**
+   * Return the token representing the keyword.
+   * @return the token representing the keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+  }
+}
+/**
+ * Instances of the class {@code SwitchCase} represent the case in a switch statement.
+ * <pre>
+ * switchCase ::={@link SimpleIdentifier label}* 'case' {@link Expression expression} ':' {@link Statement statement}</pre>
+ */
+class SwitchCase extends SwitchMember {
+  /**
+   * The expression controlling whether the statements will be executed.
+   */
+  Expression _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) : super(labels, keyword, colon, statements) {
+    this._expression = becomeParentOf(expression);
+  }
+  accept(ASTVisitor visitor) => visitor.visitSwitchCase(this);
+  /**
+   * Return the expression controlling whether the statements will be executed.
+   * @return the expression controlling whether the statements will be executed
+   */
+  Expression get expression => _expression;
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    labels.accept(visitor);
+    safelyVisitChild(_expression, visitor);
+    statements.accept(visitor);
+  }
+}
+/**
+ * Instances of the class {@code SwitchDefault} represent the default case in a switch statement.
+ * <pre>
+ * switchDefault ::={@link SimpleIdentifier label}* 'default' ':' {@link Statement statement}</pre>
+ */
+class SwitchDefault extends SwitchMember {
+  /**
+   * 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) : super(labels, keyword, colon, statements) {
+  }
+  accept(ASTVisitor visitor) => visitor.visitSwitchDefault(this);
+  void visitChildren(ASTVisitor<Object> visitor) {
+    labels.accept(visitor);
+    statements.accept(visitor);
+  }
+}
+/**
+ * The abstract class {@code SwitchMember} defines the behavior common to objects representing
+ * elements within a switch statement.
+ * <pre>
+ * switchMember ::=
+ * switchCase
+ * | switchDefault
+ * </pre>
+ */
+abstract class SwitchMember extends ASTNode {
+  /**
+   * The labels associated with the switch member.
+   */
+  NodeList<Label> _labels;
+  /**
+   * The token representing the 'case' or 'default' keyword.
+   */
+  Token _keyword;
+  /**
+   * The colon separating the keyword or the expression from the statements.
+   */
+  Token _colon;
+  /**
+   * The statements that will be executed if this switch member is selected.
+   */
+  NodeList<Statement> _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._labels = new NodeList<Label>(this);
+    this._statements = new NodeList<Statement>(this);
+    this._labels.addAll(labels);
+    this._keyword = keyword;
+    this._colon = colon;
+    this._statements.addAll(statements);
+  }
+  Token get beginToken {
+    if (!_labels.isEmpty) {
+      return _labels.beginToken;
+    }
+    return _keyword;
+  }
+  /**
+   * Return the colon separating the keyword or the expression from the statements.
+   * @return the colon separating the keyword or the expression from the statements
+   */
+  Token get colon => _colon;
+  Token get endToken {
+    if (!_statements.isEmpty) {
+      return _statements.endToken;
+    }
+    return _colon;
+  }
+  /**
+   * Return the token representing the 'case' or 'default' keyword.
+   * @return the token representing the 'case' or 'default' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * Return the labels associated with the switch member.
+   * @return the labels associated with the switch member
+   */
+  NodeList<Label> get labels => _labels;
+  /**
+   * Return the statements that will be executed if this switch member is selected.
+   * @return the statements that will be executed if this switch member is selected
+   */
+  NodeList<Statement> get statements => _statements;
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+}
+/**
+ * Instances of the class {@code SwitchStatement} represent a switch statement.
+ * <pre>
+ * switchStatement ::=
+ * 'switch' '(' {@link Expression expression} ')' '{' {@link SwitchCase switchCase}* {@link SwitchDefault defaultCase}? '}'
+ * </pre>
+ */
+class SwitchStatement extends Statement {
+  /**
+   * The token representing the 'switch' keyword.
+   */
+  Token _keyword;
+  /**
+   * The left parenthesis.
+   */
+  Token _leftParenthesis;
+  /**
+   * The expression used to determine which of the switch members will be selected.
+   */
+  Expression _expression;
+  /**
+   * The right parenthesis.
+   */
+  Token _rightParenthesis;
+  /**
+   * The left curly bracket.
+   */
+  Token _leftBracket;
+  /**
+   * The switch members that can be selected by the expression.
+   */
+  NodeList<SwitchMember> _members;
+  /**
+   * The right curly bracket.
+   */
+  Token _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._members = new NodeList<SwitchMember>(this);
+    this._keyword = keyword;
+    this._leftParenthesis = leftParenthesis;
+    this._expression = becomeParentOf(expression);
+    this._rightParenthesis = rightParenthesis;
+    this._leftBracket = leftBracket;
+    this._members.addAll(members);
+    this._rightBracket = rightBracket;
+  }
+  accept(ASTVisitor visitor) => visitor.visitSwitchStatement(this);
+  Token get beginToken => _keyword;
+  Token get endToken => _rightBracket;
+  /**
+   * Return the expression used to determine which of the switch members will be selected.
+   * @return the expression used to determine which of the switch members will be selected
+   */
+  Expression get expression => _expression;
+  /**
+   * Return the token representing the 'switch' keyword.
+   * @return the token representing the 'switch' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * Return the left curly bracket.
+   * @return the left curly bracket
+   */
+  Token get leftBracket => _leftBracket;
+  /**
+   * Return the left parenthesis.
+   * @return the left parenthesis
+   */
+  Token get leftParenthesis => _leftParenthesis;
+  /**
+   * Return the switch members that can be selected by the expression.
+   * @return the switch members that can be selected by the expression
+   */
+  NodeList<SwitchMember> get members => _members;
+  /**
+   * Return the right curly bracket.
+   * @return the right curly bracket
+   */
+  Token get rightBracket => _rightBracket;
+  /**
+   * Return the right parenthesis.
+   * @return the right parenthesis
+   */
+  Token get rightParenthesis => _rightParenthesis;
+  /**
+   * Set the expression used to determine which of the switch members will be selected to the given
+   * 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);
+  }
+  /**
+   * 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;
+  }
+  /**
+   * Set the left curly bracket to the given token.
+   * @param leftBracket the left curly bracket
+   */
+  void set leftBracket8(Token leftBracket) {
+    this._leftBracket = leftBracket;
+  }
+  /**
+   * Set the left parenthesis to the given token.
+   * @param leftParenthesis the left parenthesis
+   */
+  void set leftParenthesis11(Token leftParenthesis) {
+    this._leftParenthesis = leftParenthesis;
+  }
+  /**
+   * Set the right curly bracket to the given token.
+   * @param rightBracket the right curly bracket
+   */
+  void set rightBracket8(Token rightBracket) {
+    this._rightBracket = rightBracket;
+  }
+  /**
+   * Set the right parenthesis to the given token.
+   * @param rightParenthesis the right parenthesis
+   */
+  void set rightParenthesis11(Token rightParenthesis) {
+    this._rightParenthesis = rightParenthesis;
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_expression, visitor);
+    _members.accept(visitor);
+  }
+}
+/**
+ * Instances of the class {@code ThisExpression} represent a this expression.
+ * <pre>
+ * thisExpression ::=
+ * 'this'
+ * </pre>
+ */
+class ThisExpression extends Expression {
+  /**
+   * The token representing the keyword.
+   */
+  Token _keyword;
+  /**
+   * Initialize a newly created this expression.
+   * @param keyword the token representing the keyword
+   */
+  ThisExpression(Token keyword) {
+    this._keyword = keyword;
+  }
+  accept(ASTVisitor visitor) => visitor.visitThisExpression(this);
+  Token get beginToken => _keyword;
+  Token get endToken => _keyword;
+  /**
+   * Return the token representing the keyword.
+   * @return the token representing the keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+  }
+}
+/**
+ * Instances of the class {@code ThrowExpression} represent a throw expression.
+ * <pre>
+ * throwExpression ::=
+ * 'throw' {@link Expression expression}? ';'
+ * </pre>
+ */
+class ThrowExpression extends Expression {
+  /**
+   * The token representing the 'throw' keyword.
+   */
+  Token _keyword;
+  /**
+   * The expression computing the exception to be thrown, or {@code null} if the current exception
+   * is to be re-thrown. (The latter case can only occur if the throw statement is inside a catch
+   * clause.)
+   */
+  Expression _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._keyword = keyword;
+    this._expression = becomeParentOf(expression);
+  }
+  accept(ASTVisitor visitor) => visitor.visitThrowExpression(this);
+  Token get beginToken => _keyword;
+  Token get endToken {
+    if (_expression != null) {
+      return _expression.endToken;
+    }
+    return _keyword;
+  }
+  /**
+   * Return the expression computing the exception to be thrown, or {@code null} if the current
+   * exception is to be re-thrown. (The latter case can only occur if the throw statement is inside
+   * a catch clause.)
+   * @return the expression computing the exception to be thrown
+   */
+  Expression get expression => _expression;
+  /**
+   * Return the token representing the 'throw' keyword.
+   * @return the token representing the 'throw' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * 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);
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_expression, visitor);
+  }
+}
+/**
+ * Instances of the class {@code TopLevelVariableDeclaration} represent the declaration of one or
+ * more top-level variables of the same type.
+ * <pre>
+ * topLevelVariableDeclaration ::=
+ * ('final' | 'const') type? staticFinalDeclarationList ';'
+ * | variableDeclaration ';'
+ * </pre>
+ */
+class TopLevelVariableDeclaration extends CompilationUnitMember {
+  /**
+   * The top-level variables being declared.
+   */
+  VariableDeclarationList _variableList;
+  /**
+   * The semicolon terminating the declaration.
+   */
+  Token _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) : super(comment, metadata) {
+    this._variableList = becomeParentOf(variableList);
+    this._semicolon = semicolon;
+  }
+  accept(ASTVisitor visitor) => visitor.visitTopLevelVariableDeclaration(this);
+  Token get endToken => _semicolon;
+  /**
+   * Return the semicolon terminating the declaration.
+   * @return the semicolon terminating the declaration
+   */
+  Token get semicolon => _semicolon;
+  /**
+   * Return the top-level variables being declared.
+   * @return the top-level variables being declared
+   */
+  VariableDeclarationList get variables => _variableList;
+  /**
+   * 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;
+  }
+  /**
+   * 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) {
+    variableList = becomeParentOf(variableList);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_variableList, visitor);
+  }
+  Token get firstTokenAfterCommentAndMetadata => _variableList.beginToken;
+}
+/**
+ * Instances of the class {@code TryStatement} represent a try statement.
+ * <pre>
+ * tryStatement ::=
+ * 'try' {@link Block block} ({@link CatchClause catchClause}+ finallyClause? | finallyClause)
+ * finallyClause ::=
+ * 'finally' {@link Block block}</pre>
+ */
+class TryStatement extends Statement {
+  /**
+   * The token representing the 'try' keyword.
+   */
+  Token _tryKeyword;
+  /**
+   * The body of the statement.
+   */
+  Block _body;
+  /**
+   * The catch clauses contained in the try statement.
+   */
+  NodeList<CatchClause> _catchClauses;
+  /**
+   * The token representing the 'finally' keyword, or {@code null} if the statement does not contain
+   * a finally clause.
+   */
+  Token _finallyKeyword;
+  /**
+   * The finally clause contained in the try statement, or {@code null} if the statement does not
+   * contain a finally clause.
+   */
+  Block _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._catchClauses = new NodeList<CatchClause>(this);
+    this._tryKeyword = tryKeyword;
+    this._body = becomeParentOf(body);
+    this._catchClauses.addAll(catchClauses);
+    this._finallyKeyword = finallyKeyword;
+    this._finallyClause = becomeParentOf(finallyClause);
+  }
+  accept(ASTVisitor visitor) => visitor.visitTryStatement(this);
+  Token get beginToken => _tryKeyword;
+  /**
+   * Return the body of the statement.
+   * @return the body of the statement
+   */
+  Block get body => _body;
+  /**
+   * Return the catch clauses contained in the try statement.
+   * @return the catch clauses contained in the try statement
+   */
+  NodeList<CatchClause> get catchClauses => _catchClauses;
+  Token get endToken {
+    if (_finallyClause != null) {
+      return _finallyClause.endToken;
+    } else if (_finallyKeyword != null) {
+      return _finallyKeyword;
+    } else if (!_catchClauses.isEmpty) {
+      return _catchClauses.endToken;
+    }
+    return _body.endToken;
+  }
+  /**
+   * Return the finally clause contained in the try statement, or {@code null} if the statement does
+   * not contain a finally clause.
+   * @return the finally clause contained in the try statement
+   */
+  Block get finallyClause => _finallyClause;
+  /**
+   * Return the token representing the 'finally' keyword, or {@code null} if the statement does not
+   * contain a finally clause.
+   * @return the token representing the 'finally' keyword
+   */
+  Token get finallyKeyword => _finallyKeyword;
+  /**
+   * Return the token representing the 'try' keyword.
+   * @return the token representing the 'try' keyword
+   */
+  Token get tryKeyword => _tryKeyword;
+  /**
+   * Set the body of the statement to the given block.
+   * @param block the body of the statement
+   */
+  void set body9(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) {
+    _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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_body, visitor);
+    _catchClauses.accept(visitor);
+    safelyVisitChild(_finallyClause, visitor);
+  }
+}
+/**
+ * The abstract class {@code TypeAlias} defines the behavior common to declarations of type aliases.
+ * <pre>
+ * typeAlias ::=
+ * 'typedef' typeAliasBody
+ * typeAliasBody ::=
+ * classTypeAlias
+ * | functionTypeAlias
+ * </pre>
+ */
+abstract class TypeAlias extends CompilationUnitMember {
+  /**
+   * The token representing the 'typedef' keyword.
+   */
+  Token _keyword;
+  /**
+   * The semicolon terminating the declaration.
+   */
+  Token _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) : super(comment, metadata) {
+    this._keyword = keyword;
+    this._semicolon = semicolon;
+  }
+  Token get endToken => _semicolon;
+  /**
+   * Return the token representing the 'typedef' keyword.
+   * @return the token representing the 'typedef' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * Return the semicolon terminating the declaration.
+   * @return the semicolon terminating the declaration
+   */
+  Token get semicolon => _semicolon;
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  Token get firstTokenAfterCommentAndMetadata => _keyword;
+}
+/**
+ * Instances of the class {@code TypeArgumentList} represent a list of type arguments.
+ * <pre>
+ * typeArguments ::=
+ * '<' typeName (',' typeName)* '>'
+ * </pre>
+ */
+class TypeArgumentList extends ASTNode {
+  /**
+   * The left bracket.
+   */
+  Token _leftBracket;
+  /**
+   * The type arguments associated with the type.
+   */
+  NodeList<TypeName> _arguments;
+  /**
+   * The right bracket.
+   */
+  Token _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._arguments = new NodeList<TypeName>(this);
+    this._leftBracket = leftBracket;
+    this._arguments.addAll(arguments);
+    this._rightBracket = rightBracket;
+  }
+  accept(ASTVisitor visitor) => visitor.visitTypeArgumentList(this);
+  /**
+   * Return the type arguments associated with the type.
+   * @return the type arguments associated with the type
+   */
+  NodeList<TypeName> get arguments => _arguments;
+  Token get beginToken => _leftBracket;
+  Token get endToken => _rightBracket;
+  /**
+   * Return the left bracket.
+   * @return the left bracket
+   */
+  Token get leftBracket => _leftBracket;
+  /**
+   * Return the right bracket.
+   * @return the right bracket
+   */
+  Token get rightBracket => _rightBracket;
+  /**
+   * Set the left bracket to the given token.
+   * @param leftBracket the left bracket
+   */
+  void set leftBracket9(Token leftBracket) {
+    this._leftBracket = leftBracket;
+  }
+  /**
+   * Set the right bracket to the given token.
+   * @param rightBracket the right bracket
+   */
+  void set rightBracket9(Token rightBracket) {
+    this._rightBracket = rightBracket;
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    _arguments.accept(visitor);
+  }
+}
+/**
+ * Instances of the class {@code TypeName} represent the name of a type, which can optionally
+ * include type arguments.
+ * <pre>
+ * typeName ::={@link Identifier identifier} typeArguments?
+ * </pre>
+ */
+class TypeName extends ASTNode {
+  /**
+   * The name of the type.
+   */
+  Identifier _name;
+  /**
+   * The type arguments associated with the type, or {@code null} if there are no type arguments.
+   */
+  TypeArgumentList _typeArguments;
+  /**
+   * The type being named, or {@code null} if the AST structure has not been resolved.
+   */
+  Type2 _type;
+  /**
+   * 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._name = becomeParentOf(name);
+    this._typeArguments = becomeParentOf(typeArguments);
+  }
+  accept(ASTVisitor visitor) => visitor.visitTypeName(this);
+  Token get beginToken => _name.beginToken;
+  Token get endToken {
+    if (_typeArguments != null) {
+      return _typeArguments.endToken;
+    }
+    return _name.endToken;
+  }
+  /**
+   * Return the name of the type.
+   * @return the name of the type
+   */
+  Identifier get name => _name;
+  /**
+   * Return the type being named, or {@code null} if the AST structure has not been resolved.
+   * @return the type being named
+   */
+  Type2 get type => _type;
+  /**
+   * Return the type arguments associated with the type, or {@code null} if there are no type
+   * arguments.
+   * @return the type arguments associated with the type
+   */
+  TypeArgumentList get typeArguments => _typeArguments;
+  bool isSynthetic() => _name.isSynthetic() && _typeArguments == null;
+  /**
+   * Set the name of the type to the given identifier.
+   * @param identifier the name of the type
+   */
+  void set name12(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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_name, visitor);
+    safelyVisitChild(_typeArguments, visitor);
+  }
+}
+/**
+ * Instances of the class {@code TypeParameter} represent a type parameter.
+ * <pre>
+ * typeParameter ::={@link SimpleIdentifier name} ('extends' {@link TypeName bound})?
+ * </pre>
+ */
+class TypeParameter extends Declaration {
+  /**
+   * The name of the type parameter.
+   */
+  SimpleIdentifier _name;
+  /**
+   * The token representing the 'extends' keyword, or {@code null} if there was no explicit upper
+   * bound.
+   */
+  Token _keyword;
+  /**
+   * The name of the upper bound for legal arguments, or {@code null} if there was no explicit upper
+   * bound.
+   */
+  TypeName _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) : super(comment, metadata) {
+    this._name = becomeParentOf(name);
+    this._keyword = keyword;
+    this._bound = becomeParentOf(bound);
+  }
+  accept(ASTVisitor visitor) => visitor.visitTypeParameter(this);
+  /**
+   * Return the name of the upper bound for legal arguments, or {@code null} if there was no
+   * explicit upper bound.
+   * @return the name of the upper bound for legal arguments
+   */
+  TypeName get bound => _bound;
+  Token get endToken {
+    if (_bound == null) {
+      return _name.endToken;
+    }
+    return _bound.endToken;
+  }
+  /**
+   * Return the token representing the 'assert' keyword.
+   * @return the token representing the 'assert' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * Return the name of the type parameter.
+   * @return the name of the type parameter
+   */
+  SimpleIdentifier get name => _name;
+  /**
+   * 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) {
+    _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;
+  }
+  /**
+   * Set the name of the type parameter to the given identifier.
+   * @param identifier the name of the type parameter
+   */
+  void set name13(SimpleIdentifier identifier) {
+    _name = becomeParentOf(identifier);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_name, visitor);
+    safelyVisitChild(_bound, visitor);
+  }
+  Token get firstTokenAfterCommentAndMetadata => _name.beginToken;
+}
+/**
+ * Instances of the class {@code TypeParameterList} represent type parameters within a declaration.
+ * <pre>
+ * typeParameterList ::=
+ * '<' {@link TypeParameter typeParameter} (',' {@link TypeParameter typeParameter})* '>'
+ * </pre>
+ */
+class TypeParameterList extends ASTNode {
+  /**
+   * The left angle bracket.
+   */
+  Token _leftBracket;
+  /**
+   * The type parameters in the list.
+   */
+  NodeList<TypeParameter> _typeParameters;
+  /**
+   * The right angle bracket.
+   */
+  Token _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._typeParameters = new NodeList<TypeParameter>(this);
+    this._leftBracket = leftBracket;
+    this._typeParameters.addAll(typeParameters);
+    this._rightBracket = rightBracket;
+  }
+  accept(ASTVisitor visitor) => visitor.visitTypeParameterList(this);
+  Token get beginToken => _leftBracket;
+  Token get endToken => _rightBracket;
+  /**
+   * Return the left angle bracket.
+   * @return the left angle bracket
+   */
+  Token get leftBracket => _leftBracket;
+  /**
+   * Return the right angle bracket.
+   * @return the right angle bracket
+   */
+  Token get rightBracket => _rightBracket;
+  /**
+   * Return the type parameters for the type.
+   * @return the type parameters for the type
+   */
+  NodeList<TypeParameter> get typeParameters => _typeParameters;
+  void visitChildren(ASTVisitor<Object> visitor) {
+    _typeParameters.accept(visitor);
+  }
+}
+/**
+ * The abstract class {@code TypedLiteral} defines the behavior common to literals that have a type
+ * associated with them.
+ * <pre>
+ * listLiteral ::={@link ListLiteral listLiteral}| {@link MapLiteral mapLiteral}</pre>
+ */
+abstract class TypedLiteral extends Literal {
+  /**
+   * The const modifier associated with this literal, or {@code null} if the literal is not a
+   * constant.
+   */
+  Token _modifier;
+  /**
+   * The type argument associated with this literal, or {@code null} if no type arguments were
+   * declared.
+   */
+  TypeArgumentList _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._modifier = modifier;
+    this._typeArguments = becomeParentOf(typeArguments);
+  }
+  /**
+   * Return the const modifier associated with this literal.
+   * @return the const modifier associated with this literal
+   */
+  Token get modifier => _modifier;
+  /**
+   * Return the type argument associated with this literal, or {@code null} if no type arguments
+   * were declared.
+   * @return the type argument associated with this literal
+   */
+  TypeArgumentList get typeArguments => _typeArguments;
+  /**
+   * 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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_typeArguments, 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>
+ * variableDeclaration ::={@link SimpleIdentifier identifier} ('=' {@link Expression initialValue})?
+ * </pre>
+ */
+class VariableDeclaration extends Declaration {
+  /**
+   * The name of the variable being declared.
+   */
+  SimpleIdentifier _name;
+  /**
+   * The equal sign separating the variable name from the initial value, or {@code null} if the
+   * initial value was not specified.
+   */
+  Token _equals;
+  /**
+   * The expression used to compute the initial value for the variable, or {@code null} if the
+   * initial value was not specified.
+   */
+  Expression _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) : super(comment, metadata) {
+    this._name = becomeParentOf(name);
+    this._equals = equals;
+    this._initializer = becomeParentOf(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;
+  Token get endToken {
+    if (_initializer != null) {
+      return _initializer.endToken;
+    }
+    return _name.endToken;
+  }
+  /**
+   * Return the equal sign separating the variable name from the initial value, or {@code null} if
+   * the initial value was not specified.
+   * @return the equal sign separating the variable name from the initial value
+   */
+  Token get equals => _equals;
+  /**
+   * Return the expression used to compute the initial value for the variable, or {@code null} if
+   * the initial value was not specified.
+   * @return the expression used to compute the initial value for the variable
+   */
+  Expression get initializer => _initializer;
+  /**
+   * Return the name of the variable being declared.
+   * @return the name of the variable being declared
+   */
+  SimpleIdentifier get name => _name;
+  /**
+   * 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;
+  }
+  /**
+   * 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);
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_name, visitor);
+    safelyVisitChild(_initializer, visitor);
+  }
+  Token get firstTokenAfterCommentAndMetadata => _name.beginToken;
+}
+/**
+ * Instances of the class {@code VariableDeclarationList} represent the declaration of one or more
+ * variables of the same type.
+ * <pre>
+ * variableDeclarationList ::=
+ * finalConstVarOrType {@link VariableDeclaration variableDeclaration} (',' {@link VariableDeclaration variableDeclaration})
+ * finalConstVarOrType ::=
+ * | 'final' {@link TypeName type}?
+ * | 'const' {@link TypeName type}?
+ * | 'var'
+ * | {@link TypeName type}</pre>
+ */
+class VariableDeclarationList extends ASTNode {
+  /**
+   * The token representing the 'final', 'const' or 'var' keyword, or {@code null} if no keyword was
+   * included.
+   */
+  Token _keyword;
+  /**
+   * The type of the variables being declared, or {@code null} if no type was provided.
+   */
+  TypeName _type;
+  /**
+   * A list containing the individual variables being declared.
+   */
+  NodeList<VariableDeclaration> _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._variables = new NodeList<VariableDeclaration>(this);
+    this._keyword = keyword;
+    this._type = becomeParentOf(type);
+    this._variables.addAll(variables);
+  }
+  accept(ASTVisitor visitor) => visitor.visitVariableDeclarationList(this);
+  Token get beginToken {
+    if (_keyword != null) {
+      return _keyword;
+    } else if (_type != null) {
+      return _type.beginToken;
+    }
+    return _variables.beginToken;
+  }
+  Token get endToken => _variables.endToken;
+  /**
+   * Return the token representing the 'final', 'const' or 'var' keyword, or {@code null} if no
+   * keyword was included.
+   * @return the token representing the 'final', 'const' or 'var' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * Return the type of the variables being declared, or {@code null} if no type was provided.
+   * @return the type of the variables being declared
+   */
+  TypeName get type => _type;
+  /**
+   * Return a list containing the individual variables being declared.
+   * @return a list containing the individual variables being declared
+   */
+  NodeList<VariableDeclaration> get variables => _variables;
+  /**
+   * 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;
+  }
+  /**
+   * 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) {
+    _type = becomeParentOf(typeName);
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_type, visitor);
+    _variables.accept(visitor);
+  }
+}
+/**
+ * Instances of the class {@code VariableDeclarationStatement} represent a list of variables that
+ * are being declared in a context where a statement is required.
+ * <pre>
+ * variableDeclarationStatement ::={@link VariableDeclarationList variableList} ';'
+ * </pre>
+ */
+class VariableDeclarationStatement extends Statement {
+  /**
+   * The variables being declared.
+   */
+  VariableDeclarationList _variableList;
+  /**
+   * The semicolon terminating the statement.
+   */
+  Token _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._variableList = becomeParentOf(variableList);
+    this._semicolon = semicolon;
+  }
+  accept(ASTVisitor visitor) => visitor.visitVariableDeclarationStatement(this);
+  Token get beginToken => _variableList.beginToken;
+  Token get endToken => _semicolon;
+  /**
+   * Return the semicolon terminating the statement.
+   * @return the semicolon terminating the statement
+   */
+  Token get semicolon => _semicolon;
+  /**
+   * Return the variables being declared.
+   * @return the variables being declared
+   */
+  VariableDeclarationList get variables => _variableList;
+  /**
+   * 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;
+  }
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_variableList, visitor);
+  }
+}
+/**
+ * Instances of the class {@code WhileStatement} represent a while statement.
+ * <pre>
+ * whileStatement ::=
+ * 'while' '(' {@link Expression condition} ')' {@link Statement body}</pre>
+ */
+class WhileStatement extends Statement {
+  /**
+   * The token representing the 'while' keyword.
+   */
+  Token _keyword;
+  /**
+   * The left parenthesis.
+   */
+  Token _leftParenthesis;
+  /**
+   * The expression used to determine whether to execute the body of the loop.
+   */
+  Expression _condition;
+  /**
+   * The right parenthesis.
+   */
+  Token _rightParenthesis;
+  /**
+   * The body of the loop.
+   */
+  Statement _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._keyword = keyword;
+    this._leftParenthesis = leftParenthesis;
+    this._condition = becomeParentOf(condition);
+    this._rightParenthesis = rightParenthesis;
+    this._body = becomeParentOf(body);
+  }
+  accept(ASTVisitor visitor) => visitor.visitWhileStatement(this);
+  Token get beginToken => _keyword;
+  /**
+   * Return the body of the loop.
+   * @return the body of the loop
+   */
+  Statement get body => _body;
+  /**
+   * Return the expression used to determine whether to execute the body of the loop.
+   * @return the expression used to determine whether to execute the body of the loop
+   */
+  Expression get condition => _condition;
+  Token get endToken => _body.endToken;
+  /**
+   * Return the token representing the 'while' keyword.
+   * @return the token representing the 'while' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * Return the left parenthesis.
+   * @return the left parenthesis
+   */
+  Token get leftParenthesis => _leftParenthesis;
+  /**
+   * Return the right parenthesis.
+   * @return the right parenthesis
+   */
+  Token get rightParenthesis => _rightParenthesis;
+  /**
+   * Set the body of the loop to the given statement.
+   * @param statement the body of the loop
+   */
+  void set body10(Statement statement) {
+    _body = becomeParentOf(statement);
+  }
+  /**
+   * Set the expression used to determine whether to execute the body of the loop to the given
+   * expression.
+   * @param expression the expression used to determine whether to execute the body of the loop
+   */
+  void set condition7(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;
+  }
+  /**
+   * Set the left parenthesis to the given token.
+   * @param leftParenthesis the left parenthesis
+   */
+  void set leftParenthesis12(Token leftParenthesis) {
+    this._leftParenthesis = leftParenthesis;
+  }
+  /**
+   * Set the right parenthesis to the given token.
+   * @param rightParenthesis the right parenthesis
+   */
+  void set rightParenthesis12(Token rightParenthesis) {
+    this._rightParenthesis = rightParenthesis;
+  }
+  void visitChildren(ASTVisitor<Object> visitor) {
+    safelyVisitChild(_condition, visitor);
+    safelyVisitChild(_body, visitor);
+  }
+}
+/**
+ * Instances of the class {@code WithClause} represent the with clause in a class declaration.
+ * <pre>
+ * withClause ::=
+ * 'with' {@link TypeName mixin} (',' {@link TypeName mixin})
+ * </pre>
+ */
+class WithClause extends ASTNode {
+  /**
+   * The token representing the 'with' keyword.
+   */
+  Token _withKeyword;
+  /**
+   * The names of the mixins that were specified.
+   */
+  NodeList<TypeName> _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._mixinTypes = new NodeList<TypeName>(this);
+    this._withKeyword = withKeyword;
+    this._mixinTypes.addAll(mixinTypes);
+  }
+  accept(ASTVisitor visitor) => visitor.visitWithClause(this);
+  Token get beginToken => _withKeyword;
+  Token get endToken => _mixinTypes.endToken;
+  /**
+   * Return the names of the mixins that were specified.
+   * @return the names of the mixins that were specified
+   */
+  NodeList<TypeName> get mixinTypes => _mixinTypes;
+  /**
+   * Return the token representing the 'with' keyword.
+   * @return the token representing the 'with' keyword
+   */
+  Token get withKeyword => _withKeyword;
+  /**
+   * 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 visitChildren(ASTVisitor<Object> visitor) {
+    _mixinTypes.accept(visitor);
+  }
+}
+/**
+ * Instances of the class {@code ConstantEvaluator} evaluate constant expressions to produce their
+ * compile-time value. According to the Dart Language Specification: <blockquote> A constant
+ * expression is one of the following:
+ * <ul>
+ * <li>A literal number.</li>
+ * <li>A literal boolean.</li>
+ * <li>A literal string where any interpolated expression is a compile-time constant that evaluates
+ * to a numeric, string or boolean value or to {@code null}.</li>
+ * <li>{@code null}.</li>
+ * <li>A reference to a static constant variable.</li>
+ * <li>An identifier expression that denotes a constant variable, a class or a type variable.</li>
+ * <li>A constant constructor invocation.</li>
+ * <li>A constant list literal.</li>
+ * <li>A constant map literal.</li>
+ * <li>A simple or qualified identifier denoting a top-level function or a static method.</li>
+ * <li>A parenthesized expression {@code (e)} where {@code e} is a constant expression.</li>
+ * <li>An expression of one of the forms {@code identical(e1, e2)}, {@code e1 == e2},{@code e1 != e2} where {@code e1} and {@code e2} are constant expressions that evaluate to a
+ * numeric, string or boolean value or to {@code null}.</li>
+ * <li>An expression of one of the forms {@code !e}, {@code e1 && e2} or {@code e1 || e2}, where{@code e}, {@code e1} and {@code e2} are constant expressions that evaluate to a boolean value or
+ * to {@code null}.</li>
+ * <li>An expression of one of the forms {@code ~e}, {@code e1 ^ e2}, {@code e1 & e2},{@code e1 | e2}, {@code e1 >> e2} or {@code e1 << e2}, where {@code e}, {@code e1} and {@code e2}are constant expressions that evaluate to an integer value or to {@code null}.</li>
+ * <li>An expression of one of the forms {@code -e}, {@code e1 + e2}, {@code e1 - e2},{@code e1 * e2}, {@code e1 / e2}, {@code e1 ~/ e2}, {@code e1 > e2}, {@code e1 < e2},{@code e1 >= e2}, {@code e1 <= e2} or {@code e1 % e2}, where {@code e}, {@code e1} and {@code e2}are constant expressions that evaluate to a numeric value or to {@code null}.</li>
+ * </ul>
+ * </blockquote> The values returned by instances of this class are therefore {@code null} and
+ * instances of the classes {@code Boolean}, {@code BigInteger}, {@code Double}, {@code String}, and{@code DartObject}.
+ * <p>
+ * In addition, this class defines several values that can be returned to indicate various
+ * conditions encountered during evaluation. These are documented with the static field that define
+ * those values.
+ */
+class ConstantEvaluator extends GeneralizingASTVisitor<Object> {
+  /**
+   * The value returned for expressions (or non-expression nodes) that are not compile-time constant
+   * expressions.
+   */
+  static Object NOT_A_CONSTANT = new Object();
+  Object visitAdjacentStrings(AdjacentStrings node) {
+    StringBuffer builder = new StringBuffer();
+    for (StringLiteral string in node.strings) {
+      Object value = string.accept(this);
+      if (value == ConstantEvaluator.NOT_A_CONSTANT) {
+        return value;
+      }
+      builder.add(value);
+    }
+    return builder.toString();
+  }
+  Object visitBinaryExpression(BinaryExpression node) {
+    Object leftOperand3 = node.leftOperand.accept(this);
+    if (leftOperand3 == ConstantEvaluator.NOT_A_CONSTANT) {
+      return leftOperand3;
+    }
+    Object rightOperand3 = node.rightOperand.accept(this);
+    if (rightOperand3 == ConstantEvaluator.NOT_A_CONSTANT) {
+      return rightOperand3;
+    }
+    if (node.operator.type == TokenType.AMPERSAND) {
+      if (leftOperand3 is int && rightOperand3 is int) {
+        return (leftOperand3 as int) & rightOperand3 as int;
+      }
+    } else if (node.operator.type == TokenType.AMPERSAND_AMPERSAND) {
+      if (leftOperand3 is bool && rightOperand3 is bool) {
+        return (leftOperand3 as bool) && (rightOperand3 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;
+      }
+    } else if (node.operator.type == TokenType.BAR) {
+      if (leftOperand3 is int && rightOperand3 is int) {
+        return (leftOperand3 as int) | rightOperand3 as int;
+      }
+    } else if (node.operator.type == TokenType.BAR_BAR) {
+      if (leftOperand3 is bool && rightOperand3 is bool) {
+        return (leftOperand3 as bool) || (rightOperand3 as bool);
+      }
+    } else if (node.operator.type == TokenType.CARET) {
+      if (leftOperand3 is int && rightOperand3 is int) {
+        return (leftOperand3 as int) ^ rightOperand3 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;
+      }
+    } 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;
+      }
+    } 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;
+      }
+    } else if (node.operator.type == TokenType.GT_GT) {
+      if (leftOperand3 is int && rightOperand3 is int) {
+        return (leftOperand3 as int) >> (rightOperand3 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;
+      }
+    } 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;
+      }
+    } else if (node.operator.type == TokenType.LT_LT) {
+      if (leftOperand3 is int && rightOperand3 is int) {
+        return (leftOperand3 as int) << (rightOperand3 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);
+      }
+    } 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);
+      }
+    } 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);
+      }
+    } 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);
+      }
+    } 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);
+      }
+    } 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);
+      }
+    }
+    return visitExpression(node);
+  }
+  Object visitBooleanLiteral(BooleanLiteral node) => node.value ? true : false;
+  Object visitDoubleLiteral(DoubleLiteral node) => node.value;
+  Object visitIntegerLiteral(IntegerLiteral node) => node.value;
+  Object visitInterpolationExpression(InterpolationExpression node) {
+    Object value = node.expression.accept(this);
+    if (value == null || value is bool || value is String || value is int || value is double) {
+      return value;
+    }
+    return NOT_A_CONSTANT;
+  }
+  Object visitInterpolationString(InterpolationString node) => node.value;
+  Object visitListLiteral(ListLiteral node) {
+    List<Object> list = new List<Object>();
+    for (Expression element in node.elements) {
+      Object value = element.accept(this);
+      if (value == ConstantEvaluator.NOT_A_CONSTANT) {
+        return value;
+      }
+      list.add(value);
+    }
+    return list;
+  }
+  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) {
+        return NOT_A_CONSTANT;
+      }
+      map[key3 as String] = value10;
+    }
+    return map;
+  }
+  Object visitMethodInvocation(MethodInvocation node) => visitNode(node);
+  Object visitNode(ASTNode node) => NOT_A_CONSTANT;
+  Object visitNullLiteral(NullLiteral node) => null;
+  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;
+    }
+    if (node.operator.type == TokenType.BANG) {
+      if (operand4 == true) {
+        return false;
+      } else if (operand4 == false) {
+        return true;
+      }
+    } else if (node.operator.type == TokenType.TILDE) {
+      if (operand4 is int) {
+        return ~(operand4 as int);
+      }
+    } else if (node.operator.type == TokenType.MINUS) {
+      if (operand4 == null) {
+        return null;
+      } else if (operand4 is int) {
+        return -(operand4 as int);
+      } else if (operand4 is double) {
+        return -(operand4 as double);
+      }
+    }
+    return NOT_A_CONSTANT;
+  }
+  Object visitPropertyAccess(PropertyAccess node) => getConstantValue(null);
+  Object visitSimpleIdentifier(SimpleIdentifier node) => getConstantValue(null);
+  Object visitSimpleStringLiteral(SimpleStringLiteral node) => node.value;
+  Object visitStringInterpolation(StringInterpolation node) {
+    StringBuffer builder = new StringBuffer();
+    for (InterpolationElement element in node.elements) {
+      Object value = element.accept(this);
+      if (value == ConstantEvaluator.NOT_A_CONSTANT) {
+        return value;
+      }
+      builder.add(value);
+    }
+    return builder.toString();
+  }
+  /**
+   * Return the constant value of the static constant represented by the given element.
+   * @param element the element whose value is to be returned
+   * @return the constant value of the static constant
+   */
+  Object getConstantValue(Element element) {
+    if (element is FieldElement) {
+      FieldElement field = element as FieldElement;
+      if (field.isStatic() && field.isConst()) {
+      }
+    }
+    return NOT_A_CONSTANT;
+  }
+}
+/**
+ * Instances of the class {@code GeneralizingASTVisitor} implement an AST visitor that will
+ * recursively visit all of the nodes in an AST structure (like instances of the class{@link RecursiveASTVisitor}). In addition, when a node of a specific type is visited not only
+ * will the visit method for that specific type of node be invoked, but additional methods for the
+ * superclasses of that node will also be invoked. For example, using an instance of this class to
+ * visit a {@link Block} will cause the method {@link #visitBlock(Block)} to be invoked but will
+ * also cause the methods {@link #visitStatement(Statement)} and {@link #visitNode(ASTNode)} to be
+ * subsequently invoked. This allows visitors to be written that visit all statements without
+ * needing to override the visit method for each of the specific subclasses of {@link Statement}.
+ * <p>
+ * Subclasses that override a visit method must either invoke the overridden visit method or
+ * explicitly invoke the more general visit method. Failure to do so will cause the visit methods
+ * for superclasses of the node to not be invoked and will cause the children of the visited node to
+ * not be visited.
+ */
+class GeneralizingASTVisitor<R> implements ASTVisitor<R> {
+  R visitAdjacentStrings(AdjacentStrings node) => visitStringLiteral(node);
+  R visitAnnotatedNode(AnnotatedNode node) => visitNode(node);
+  R visitAnnotation(Annotation node) => visitNode(node);
+  R visitArgumentDefinitionTest(ArgumentDefinitionTest node) => visitExpression(node);
+  R visitArgumentList(ArgumentList node) => visitNode(node);
+  R visitAsExpression(AsExpression node) => visitExpression(node);
+  R visitAssertStatement(AssertStatement node) => visitStatement(node);
+  R visitAssignmentExpression(AssignmentExpression node) => visitExpression(node);
+  R visitBinaryExpression(BinaryExpression node) => visitExpression(node);
+  R visitBlock(Block node) => visitStatement(node);
+  R visitBlockFunctionBody(BlockFunctionBody node) => visitFunctionBody(node);
+  R visitBooleanLiteral(BooleanLiteral node) => visitLiteral(node);
+  R visitBreakStatement(BreakStatement node) => visitStatement(node);
+  R visitCascadeExpression(CascadeExpression node) => visitExpression(node);
+  R visitCatchClause(CatchClause node) => visitNode(node);
+  R visitClassDeclaration(ClassDeclaration node) => visitCompilationUnitMember(node);
+  R visitClassMember(ClassMember node) => visitDeclaration(node);
+  R visitClassTypeAlias(ClassTypeAlias node) => visitTypeAlias(node);
+  R visitCombinator(Combinator node) => visitNode(node);
+  R visitComment(Comment node) => visitNode(node);
+  R visitCommentReference(CommentReference node) => visitNode(node);
+  R visitCompilationUnit(CompilationUnit node) => visitNode(node);
+  R visitCompilationUnitMember(CompilationUnitMember node) => visitDeclaration(node);
+  R visitConditionalExpression(ConditionalExpression node) => visitExpression(node);
+  R visitConstructorDeclaration(ConstructorDeclaration node) => visitClassMember(node);
+  R visitConstructorFieldInitializer(ConstructorFieldInitializer node) => visitConstructorInitializer(node);
+  R visitConstructorInitializer(ConstructorInitializer node) => visitNode(node);
+  R visitConstructorName(ConstructorName node) => visitNode(node);
+  R visitContinueStatement(ContinueStatement node) => visitStatement(node);
+  R visitDeclaration(Declaration node) => visitAnnotatedNode(node);
+  R visitDefaultFormalParameter(DefaultFormalParameter node) => visitFormalParameter(node);
+  R visitDirective(Directive node) => visitAnnotatedNode(node);
+  R visitDoStatement(DoStatement node) => visitStatement(node);
+  R visitDoubleLiteral(DoubleLiteral node) => visitLiteral(node);
+  R visitEmptyFunctionBody(EmptyFunctionBody node) => visitFunctionBody(node);
+  R visitEmptyStatement(EmptyStatement node) => visitStatement(node);
+  R visitExportDirective(ExportDirective node) => visitNamespaceDirective(node);
+  R visitExpression(Expression node) => visitNode(node);
+  R visitExpressionFunctionBody(ExpressionFunctionBody node) => visitFunctionBody(node);
+  R visitExpressionStatement(ExpressionStatement node) => visitStatement(node);
+  R visitExtendsClause(ExtendsClause node) => visitNode(node);
+  R visitFieldDeclaration(FieldDeclaration node) => visitClassMember(node);
+  R visitFieldFormalParameter(FieldFormalParameter node) => visitNormalFormalParameter(node);
+  R visitForEachStatement(ForEachStatement node) => visitStatement(node);
+  R visitFormalParameter(FormalParameter node) => visitNode(node);
+  R visitFormalParameterList(FormalParameterList node) => visitNode(node);
+  R visitForStatement(ForStatement node) => visitStatement(node);
+  R visitFunctionBody(FunctionBody node) => visitNode(node);
+  R visitFunctionDeclaration(FunctionDeclaration node) => visitNode(node);
+  R visitFunctionDeclarationStatement(FunctionDeclarationStatement node) => visitStatement(node);
+  R visitFunctionExpression(FunctionExpression node) => visitExpression(node);
+  R visitFunctionExpressionInvocation(FunctionExpressionInvocation node) => visitExpression(node);
+  R visitFunctionTypeAlias(FunctionTypeAlias node) => visitTypeAlias(node);
+  R visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) => visitNormalFormalParameter(node);
+  R visitHideCombinator(HideCombinator node) => visitCombinator(node);
+  R visitIdentifier(Identifier node) => visitExpression(node);
+  R visitIfStatement(IfStatement node) => visitStatement(node);
+  R visitImplementsClause(ImplementsClause node) => visitNode(node);
+  R visitImportDirective(ImportDirective node) => visitNamespaceDirective(node);
+  R visitIndexExpression(IndexExpression node) => visitExpression(node);
+  R visitInstanceCreationExpression(InstanceCreationExpression node) => visitExpression(node);
+  R visitIntegerLiteral(IntegerLiteral node) => visitLiteral(node);
+  R visitInterpolationElement(InterpolationElement node) => visitNode(node);
+  R visitInterpolationExpression(InterpolationExpression node) => visitInterpolationElement(node);
+  R visitInterpolationString(InterpolationString node) => visitInterpolationElement(node);
+  R visitIsExpression(IsExpression node) => visitExpression(node);
+  R visitLabel(Label node) => visitNode(node);
+  R visitLabeledStatement(LabeledStatement node) => visitStatement(node);
+  R visitLibraryDirective(LibraryDirective node) => visitDirective(node);
+  R visitLibraryIdentifier(LibraryIdentifier node) => visitIdentifier(node);
+  R visitListLiteral(ListLiteral node) => visitTypedLiteral(node);
+  R visitLiteral(Literal node) => visitExpression(node);
+  R visitMapLiteral(MapLiteral node) => visitTypedLiteral(node);
+  R visitMapLiteralEntry(MapLiteralEntry node) => visitNode(node);
+  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 visitNode(ASTNode node) {
+    node.visitChildren(this);
+    return null;
+  }
+  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 visitPartOfDirective(PartOfDirective node) => visitDirective(node);
+  R visitPostfixExpression(PostfixExpression node) => visitExpression(node);
+  R visitPrefixedIdentifier(PrefixedIdentifier node) => visitIdentifier(node);
+  R visitPrefixExpression(PrefixExpression node) => visitExpression(node);
+  R visitPropertyAccess(PropertyAccess node) => visitExpression(node);
+  R visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) => visitConstructorInitializer(node);
+  R visitReturnStatement(ReturnStatement node) => visitStatement(node);
+  R visitScriptTag(ScriptTag scriptTag) => visitNode(scriptTag);
+  R visitShowCombinator(ShowCombinator node) => visitCombinator(node);
+  R visitSimpleFormalParameter(SimpleFormalParameter node) => visitNormalFormalParameter(node);
+  R visitSimpleIdentifier(SimpleIdentifier node) => visitIdentifier(node);
+  R visitSimpleStringLiteral(SimpleStringLiteral node) => visitStringLiteral(node);
+  R visitStatement(Statement node) => visitNode(node);
+  R visitStringInterpolation(StringInterpolation node) => visitStringLiteral(node);
+  R visitStringLiteral(StringLiteral node) => visitLiteral(node);
+  R visitSuperConstructorInvocation(SuperConstructorInvocation node) => visitConstructorInitializer(node);
+  R visitSuperExpression(SuperExpression node) => visitExpression(node);
+  R visitSwitchCase(SwitchCase node) => visitSwitchMember(node);
+  R visitSwitchDefault(SwitchDefault node) => visitSwitchMember(node);
+  R visitSwitchMember(SwitchMember node) => visitNode(node);
+  R visitSwitchStatement(SwitchStatement node) => visitStatement(node);
+  R visitThisExpression(ThisExpression node) => visitExpression(node);
+  R visitThrowExpression(ThrowExpression node) => visitExpression(node);
+  R visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) => visitCompilationUnitMember(node);
+  R visitTryStatement(TryStatement node) => visitStatement(node);
+  R visitTypeAlias(TypeAlias node) => visitCompilationUnitMember(node);
+  R visitTypeArgumentList(TypeArgumentList node) => visitNode(node);
+  R visitTypedLiteral(TypedLiteral node) => visitLiteral(node);
+  R visitTypeName(TypeName node) => visitNode(node);
+  R visitTypeParameter(TypeParameter node) => visitNode(node);
+  R visitTypeParameterList(TypeParameterList node) => visitNode(node);
+  R visitVariableDeclaration(VariableDeclaration node) => visitDeclaration(node);
+  R visitVariableDeclarationList(VariableDeclarationList node) => visitNode(node);
+  R visitVariableDeclarationStatement(VariableDeclarationStatement node) => visitStatement(node);
+  R visitWhileStatement(WhileStatement node) => visitStatement(node);
+  R visitWithClause(WithClause node) => visitNode(node);
+}
+/**
+ * Instances of the class {@code NodeFoundException} are used to cancel visiting after a node has
+ * been found.
+ */
+class NodeLocator_NodeFoundException extends RuntimeException {
+  static int _serialVersionUID = 1;
+}
+/**
+ * Instances of the class {@code RecursiveASTVisitor} implement an AST visitor that will recursively
+ * visit all of the nodes in an AST structure. For example, using an instance of this class to visit
+ * a {@link Block} will also cause all of the statements in the block to be visited.
+ * <p>
+ * Subclasses that override a visit method must either invoke the overridden visit method or must
+ * explicitly ask the visited node to visit its children. Failure to do so will cause the children
+ * of the visited node to not be visited.
+ */
+class RecursiveASTVisitor<R> implements ASTVisitor<R> {
+  R visitAdjacentStrings(AdjacentStrings node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitAnnotation(Annotation node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitArgumentDefinitionTest(ArgumentDefinitionTest node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitArgumentList(ArgumentList node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitAsExpression(AsExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitAssertStatement(AssertStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitAssignmentExpression(AssignmentExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitBinaryExpression(BinaryExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitBlock(Block node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitBlockFunctionBody(BlockFunctionBody node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitBooleanLiteral(BooleanLiteral node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitBreakStatement(BreakStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitCascadeExpression(CascadeExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitCatchClause(CatchClause node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitClassDeclaration(ClassDeclaration node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitClassTypeAlias(ClassTypeAlias node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitComment(Comment node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitCommentReference(CommentReference node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitCompilationUnit(CompilationUnit node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitConditionalExpression(ConditionalExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitConstructorDeclaration(ConstructorDeclaration node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitConstructorName(ConstructorName node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitContinueStatement(ContinueStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitDefaultFormalParameter(DefaultFormalParameter node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitDoStatement(DoStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitDoubleLiteral(DoubleLiteral node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitEmptyFunctionBody(EmptyFunctionBody node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitEmptyStatement(EmptyStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitExportDirective(ExportDirective node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitExpressionStatement(ExpressionStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitExtendsClause(ExtendsClause node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitFieldDeclaration(FieldDeclaration node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitFieldFormalParameter(FieldFormalParameter node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitForEachStatement(ForEachStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitFormalParameterList(FormalParameterList node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitForStatement(ForStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitFunctionDeclaration(FunctionDeclaration node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitFunctionExpression(FunctionExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitFunctionTypeAlias(FunctionTypeAlias node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitHideCombinator(HideCombinator node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitIfStatement(IfStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitImplementsClause(ImplementsClause node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitImportDirective(ImportDirective node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitIndexExpression(IndexExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitInstanceCreationExpression(InstanceCreationExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitIntegerLiteral(IntegerLiteral node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitInterpolationExpression(InterpolationExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitInterpolationString(InterpolationString node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitIsExpression(IsExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitLabel(Label node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitLabeledStatement(LabeledStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitLibraryDirective(LibraryDirective node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitLibraryIdentifier(LibraryIdentifier node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitListLiteral(ListLiteral node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitMapLiteral(MapLiteral node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitMapLiteralEntry(MapLiteralEntry node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitMethodDeclaration(MethodDeclaration node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitMethodInvocation(MethodInvocation node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitNamedExpression(NamedExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitNullLiteral(NullLiteral node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitParenthesizedExpression(ParenthesizedExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitPartDirective(PartDirective node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitPartOfDirective(PartOfDirective node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitPostfixExpression(PostfixExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitPrefixedIdentifier(PrefixedIdentifier node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitPrefixExpression(PrefixExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitPropertyAccess(PropertyAccess node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitReturnStatement(ReturnStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitScriptTag(ScriptTag node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitShowCombinator(ShowCombinator node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitSimpleFormalParameter(SimpleFormalParameter node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitSimpleIdentifier(SimpleIdentifier node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitSimpleStringLiteral(SimpleStringLiteral node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitStringInterpolation(StringInterpolation node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitSuperExpression(SuperExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitSwitchCase(SwitchCase node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitSwitchDefault(SwitchDefault node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitSwitchStatement(SwitchStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitThisExpression(ThisExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitThrowExpression(ThrowExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitTryStatement(TryStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitTypeArgumentList(TypeArgumentList node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitTypeName(TypeName node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitTypeParameter(TypeParameter node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitTypeParameterList(TypeParameterList node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitVariableDeclaration(VariableDeclaration node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitVariableDeclarationList(VariableDeclarationList node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitWhileStatement(WhileStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
+  R visitWithClause(WithClause node) {
+    node.visitChildren(this);
+    return null;
+  }
+}
+/**
+ * Instances of the class {@code SimpleASTVisitor} implement an AST visitor that will do nothing
+ * when visiting an AST node. It is intended to be a superclass for classes that use the visitor
+ * pattern primarily as a dispatch mechanism (and hence don't need to recursively visit a whole
+ * structure) and that only need to visit a small number of node types.
+ */
+class SimpleASTVisitor<R> implements ASTVisitor<R> {
+  R visitAdjacentStrings(AdjacentStrings node) => null;
+  R visitAnnotation(Annotation node) => null;
+  R visitArgumentDefinitionTest(ArgumentDefinitionTest node) => null;
+  R visitArgumentList(ArgumentList node) => null;
+  R visitAsExpression(AsExpression node) => null;
+  R visitAssertStatement(AssertStatement node) => null;
+  R visitAssignmentExpression(AssignmentExpression node) => null;
+  R visitBinaryExpression(BinaryExpression node) => null;
+  R visitBlock(Block node) => null;
+  R visitBlockFunctionBody(BlockFunctionBody node) => null;
+  R visitBooleanLiteral(BooleanLiteral node) => null;
+  R visitBreakStatement(BreakStatement node) => null;
+  R visitCascadeExpression(CascadeExpression node) => null;
+  R visitCatchClause(CatchClause node) => null;
+  R visitClassDeclaration(ClassDeclaration node) => null;
+  R visitClassTypeAlias(ClassTypeAlias node) => null;
+  R visitComment(Comment node) => null;
+  R visitCommentReference(CommentReference node) => null;
+  R visitCompilationUnit(CompilationUnit node) => null;
+  R visitConditionalExpression(ConditionalExpression node) => null;
+  R visitConstructorDeclaration(ConstructorDeclaration node) => null;
+  R visitConstructorFieldInitializer(ConstructorFieldInitializer node) => null;
+  R visitConstructorName(ConstructorName node) => null;
+  R visitContinueStatement(ContinueStatement node) => null;
+  R visitDefaultFormalParameter(DefaultFormalParameter node) => null;
+  R visitDoStatement(DoStatement node) => null;
+  R visitDoubleLiteral(DoubleLiteral node) => null;
+  R visitEmptyFunctionBody(EmptyFunctionBody node) => null;
+  R visitEmptyStatement(EmptyStatement node) => null;
+  R visitExportDirective(ExportDirective node) => null;
+  R visitExpressionFunctionBody(ExpressionFunctionBody node) => null;
+  R visitExpressionStatement(ExpressionStatement node) => null;
+  R visitExtendsClause(ExtendsClause node) => null;
+  R visitFieldDeclaration(FieldDeclaration node) => null;
+  R visitFieldFormalParameter(FieldFormalParameter node) => null;
+  R visitForEachStatement(ForEachStatement node) => null;
+  R visitFormalParameterList(FormalParameterList node) => null;
+  R visitForStatement(ForStatement node) => null;
+  R visitFunctionDeclaration(FunctionDeclaration node) => null;
+  R visitFunctionDeclarationStatement(FunctionDeclarationStatement node) => null;
+  R visitFunctionExpression(FunctionExpression node) => null;
+  R visitFunctionExpressionInvocation(FunctionExpressionInvocation node) => null;
+  R visitFunctionTypeAlias(FunctionTypeAlias node) => null;
+  R visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) => null;
+  R visitHideCombinator(HideCombinator node) => null;
+  R visitIfStatement(IfStatement node) => null;
+  R visitImplementsClause(ImplementsClause node) => null;
+  R visitImportDirective(ImportDirective node) => null;
+  R visitIndexExpression(IndexExpression node) => null;
+  R visitInstanceCreationExpression(InstanceCreationExpression node) => null;
+  R visitIntegerLiteral(IntegerLiteral node) => null;
+  R visitInterpolationExpression(InterpolationExpression node) => null;
+  R visitInterpolationString(InterpolationString node) => null;
+  R visitIsExpression(IsExpression node) => null;
+  R visitLabel(Label node) => null;
+  R visitLabeledStatement(LabeledStatement node) => null;
+  R visitLibraryDirective(LibraryDirective node) => null;
+  R visitLibraryIdentifier(LibraryIdentifier node) => null;
+  R visitListLiteral(ListLiteral node) => null;
+  R visitMapLiteral(MapLiteral node) => null;
+  R visitMapLiteralEntry(MapLiteralEntry node) => null;
+  R visitMethodDeclaration(MethodDeclaration node) => null;
+  R visitMethodInvocation(MethodInvocation node) => null;
+  R visitNamedExpression(NamedExpression node) => null;
+  R visitNullLiteral(NullLiteral node) => null;
+  R visitParenthesizedExpression(ParenthesizedExpression node) => null;
+  R visitPartDirective(PartDirective node) => null;
+  R visitPartOfDirective(PartOfDirective node) => null;
+  R visitPostfixExpression(PostfixExpression node) => null;
+  R visitPrefixedIdentifier(PrefixedIdentifier node) => null;
+  R visitPrefixExpression(PrefixExpression node) => null;
+  R visitPropertyAccess(PropertyAccess node) => null;
+  R visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) => null;
+  R visitReturnStatement(ReturnStatement node) => null;
+  R visitScriptTag(ScriptTag node) => null;
+  R visitShowCombinator(ShowCombinator node) => null;
+  R visitSimpleFormalParameter(SimpleFormalParameter node) => null;
+  R visitSimpleIdentifier(SimpleIdentifier node) => null;
+  R visitSimpleStringLiteral(SimpleStringLiteral node) => null;
+  R visitStringInterpolation(StringInterpolation node) => null;
+  R visitSuperConstructorInvocation(SuperConstructorInvocation node) => null;
+  R visitSuperExpression(SuperExpression node) => null;
+  R visitSwitchCase(SwitchCase node) => null;
+  R visitSwitchDefault(SwitchDefault node) => null;
+  R visitSwitchStatement(SwitchStatement node) => null;
+  R visitThisExpression(ThisExpression node) => null;
+  R visitThrowExpression(ThrowExpression node) => null;
+  R visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) => null;
+  R visitTryStatement(TryStatement node) => null;
+  R visitTypeArgumentList(TypeArgumentList node) => null;
+  R visitTypeName(TypeName node) => null;
+  R visitTypeParameter(TypeParameter node) => null;
+  R visitTypeParameterList(TypeParameterList node) => null;
+  R visitVariableDeclaration(VariableDeclaration node) => null;
+  R visitVariableDeclarationList(VariableDeclarationList node) => null;
+  R visitVariableDeclarationStatement(VariableDeclarationStatement node) => null;
+  R visitWhileStatement(WhileStatement node) => null;
+  R visitWithClause(WithClause node) => null;
+}
+/**
+ * Instances of the class {@code ToSourceVisitor} write a source representation of a visited AST
+ * node (and all of it's children) to a writer.
+ */
+class ToSourceVisitor implements ASTVisitor<Object> {
+  /**
+   * The writer to which the source is to be written.
+   */
+  PrintWriter _writer;
+  /**
+   * Initialize a newly created visitor to write source code representing the visited nodes to the
+   * given writer.
+   * @param writer the writer to which the source is to be written
+   */
+  ToSourceVisitor(PrintWriter writer) {
+    this._writer = writer;
+  }
+  Object visitAdjacentStrings(AdjacentStrings node) {
+    visitList2(node.strings, " ");
+    return null;
+  }
+  Object visitAnnotation(Annotation node) {
+    _writer.print('@');
+    visit(node.name);
+    visit3(".", node.constructorName);
+    visit(node.arguments);
+    return null;
+  }
+  Object visitArgumentDefinitionTest(ArgumentDefinitionTest node) {
+    _writer.print('?');
+    visit(node.identifier);
+    return null;
+  }
+  Object visitArgumentList(ArgumentList node) {
+    _writer.print('(');
+    visitList2(node.arguments, ", ");
+    _writer.print(')');
+    return null;
+  }
+  Object visitAsExpression(AsExpression node) {
+    visit(node.expression);
+    _writer.print(" as ");
+    visit(node.type);
+    return null;
+  }
+  Object visitAssertStatement(AssertStatement node) {
+    _writer.print("assert (");
+    visit(node.condition);
+    _writer.print(");");
+    return null;
+  }
+  Object visitAssignmentExpression(AssignmentExpression node) {
+    visit(node.leftHandSide);
+    _writer.print(' ');
+    _writer.print(node.operator.lexeme);
+    _writer.print(' ');
+    visit(node.rightHandSide);
+    return null;
+  }
+  Object visitBinaryExpression(BinaryExpression node) {
+    visit(node.leftOperand);
+    _writer.print(' ');
+    _writer.print(node.operator.lexeme);
+    _writer.print(' ');
+    visit(node.rightOperand);
+    return null;
+  }
+  Object visitBlock(Block node) {
+    _writer.print('{');
+    visitList2(node.statements, " ");
+    _writer.print('}');
+    return null;
+  }
+  Object visitBlockFunctionBody(BlockFunctionBody node) {
+    visit(node.block);
+    return null;
+  }
+  Object visitBooleanLiteral(BooleanLiteral node) {
+    _writer.print(node.literal.lexeme);
+    return null;
+  }
+  Object visitBreakStatement(BreakStatement node) {
+    _writer.print("break");
+    visit3(" ", node.label);
+    _writer.print(";");
+    return null;
+  }
+  Object visitCascadeExpression(CascadeExpression node) {
+    visit(node.target);
+    visitList(node.cascadeSections);
+    return null;
+  }
+  Object visitCatchClause(CatchClause node) {
+    visit3("on ", node.exceptionType);
+    if (node.catchKeyword != null) {
+      if (node.exceptionType != null) {
+        _writer.print(' ');
+      }
+      _writer.print("catch (");
+      visit(node.exceptionParameter);
+      visit3(", ", node.stackTraceParameter);
+      _writer.print(") ");
+    } else {
+      _writer.print(" ");
+    }
+    visit(node.body);
+    return null;
+  }
+  Object visitClassDeclaration(ClassDeclaration node) {
+    visit5(node.abstractKeyword, " ");
+    _writer.print("class ");
+    visit(node.name);
+    visit(node.typeParameters);
+    visit3(" ", node.extendsClause);
+    visit3(" ", node.withClause);
+    visit3(" ", node.implementsClause);
+    _writer.print(" {");
+    visitList2(node.members, " ");
+    _writer.print("}");
+    return null;
+  }
+  Object visitClassTypeAlias(ClassTypeAlias node) {
+    _writer.print("typedef ");
+    visit(node.name);
+    visit(node.typeParameters);
+    _writer.print(" = ");
+    if (node.abstractKeyword != null) {
+      _writer.print("abstract ");
+    }
+    visit(node.superclass);
+    visit3(" ", node.withClause);
+    visit3(" ", node.implementsClause);
+    _writer.print(";");
+    return null;
+  }
+  Object visitComment(Comment node) => null;
+  Object visitCommentReference(CommentReference node) => null;
+  Object visitCompilationUnit(CompilationUnit node) {
+    ScriptTag scriptTag4 = node.scriptTag;
+    NodeList<Directive> directives2 = node.directives;
+    visit(scriptTag4);
+    String prefix = scriptTag4 == null ? "" : " ";
+    visitList4(prefix, directives2, " ");
+    prefix = scriptTag4 == null && directives2.isEmpty ? "" : " ";
+    visitList4(prefix, node.declarations, " ");
+    return null;
+  }
+  Object visitConditionalExpression(ConditionalExpression node) {
+    visit(node.condition);
+    _writer.print(" ? ");
+    visit(node.thenExpression);
+    _writer.print(" : ");
+    visit(node.elseExpression);
+    return null;
+  }
+  Object visitConstructorDeclaration(ConstructorDeclaration node) {
+    visit5(node.externalKeyword, " ");
+    visit5(node.constKeyword, " ");
+    visit5(node.factoryKeyword, " ");
+    visit(node.returnType);
+    visit3(".", node.name);
+    visit(node.parameters);
+    visitList4(" : ", node.initializers, ", ");
+    visit3(" = ", node.redirectedConstructor);
+    visit4(" ", node.body);
+    return null;
+  }
+  Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+    visit5(node.keyword, ".");
+    visit(node.fieldName);
+    _writer.print(" = ");
+    visit(node.expression);
+    return null;
+  }
+  Object visitConstructorName(ConstructorName node) {
+    visit(node.type);
+    visit3(".", node.name);
+    return null;
+  }
+  Object visitContinueStatement(ContinueStatement node) {
+    _writer.print("continue");
+    visit3(" ", node.label);
+    _writer.print(";");
+    return null;
+  }
+  Object visitDefaultFormalParameter(DefaultFormalParameter node) {
+    visit(node.parameter);
+    if (node.separator != null) {
+      _writer.print(" ");
+      _writer.print(node.separator.lexeme);
+      visit3(" ", node.defaultValue);
+    }
+    return null;
+  }
+  Object visitDoStatement(DoStatement node) {
+    _writer.print("do ");
+    visit(node.body);
+    _writer.print(" while (");
+    visit(node.condition);
+    _writer.print(");");
+    return null;
+  }
+  Object visitDoubleLiteral(DoubleLiteral node) {
+    _writer.print(node.literal.lexeme);
+    return null;
+  }
+  Object visitEmptyFunctionBody(EmptyFunctionBody node) {
+    _writer.print(';');
+    return null;
+  }
+  Object visitEmptyStatement(EmptyStatement node) {
+    _writer.print(';');
+    return null;
+  }
+  Object visitExportDirective(ExportDirective node) {
+    _writer.print("export ");
+    visit(node.libraryUri);
+    visitList4(" ", node.combinators, " ");
+    _writer.print(';');
+    return null;
+  }
+  Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    _writer.print("=> ");
+    visit(node.expression);
+    if (node.semicolon != null) {
+      _writer.print(';');
+    }
+    return null;
+  }
+  Object visitExpressionStatement(ExpressionStatement node) {
+    visit(node.expression);
+    _writer.print(';');
+    return null;
+  }
+  Object visitExtendsClause(ExtendsClause node) {
+    _writer.print("extends ");
+    visit(node.superclass);
+    return null;
+  }
+  Object visitFieldDeclaration(FieldDeclaration node) {
+    visit5(node.keyword, " ");
+    visit(node.fields);
+    _writer.print(";");
+    return null;
+  }
+  Object visitFieldFormalParameter(FieldFormalParameter node) {
+    visit5(node.keyword, " ");
+    visit2(node.type, " ");
+    _writer.print("this.");
+    visit(node.identifier);
+    return null;
+  }
+  Object visitForEachStatement(ForEachStatement node) {
+    _writer.print("for (");
+    visit(node.loopParameter);
+    _writer.print(" in ");
+    visit(node.iterator);
+    _writer.print(") ");
+    visit(node.body);
+    return null;
+  }
+  Object visitFormalParameterList(FormalParameterList node) {
+    String groupEnd = null;
+    _writer.print('(');
+    NodeList<FormalParameter> parameters9 = node.parameters;
+    int size2 = parameters9.length;
+    for (int i = 0; i < size2; i++) {
+      FormalParameter parameter = parameters9[i];
+      if (i > 0) {
+        _writer.print(", ");
+      }
+      if (groupEnd == null && parameter is DefaultFormalParameter) {
+        if (parameter.kind == ParameterKind.NAMED) {
+          groupEnd = "}";
+          _writer.print('{');
+        } else {
+          groupEnd = "]";
+          _writer.print('[');
+        }
+      }
+      parameter.accept(this);
+    }
+    if (groupEnd != null) {
+      _writer.print(groupEnd);
+    }
+    _writer.print(')');
+    return null;
+  }
+  Object visitForStatement(ForStatement node) {
+    Expression initialization3 = node.initialization;
+    _writer.print("for (");
+    if (initialization3 != null) {
+      visit(initialization3);
+    } else {
+      visit(node.variables);
+    }
+    _writer.print(";");
+    visit3(" ", node.condition);
+    _writer.print(";");
+    visitList4(" ", node.updaters, ", ");
+    _writer.print(") ");
+    visit(node.body);
+    return null;
+  }
+  Object visitFunctionDeclaration(FunctionDeclaration node) {
+    visit2(node.returnType, " ");
+    visit5(node.propertyKeyword, " ");
+    visit(node.name);
+    visit(node.functionExpression);
+    return null;
+  }
+  Object visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
+    visit(node.functionDeclaration);
+    _writer.print(';');
+    return null;
+  }
+  Object visitFunctionExpression(FunctionExpression node) {
+    visit(node.parameters);
+    _writer.print(' ');
+    visit(node.body);
+    return null;
+  }
+  Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    visit(node.function);
+    visit(node.argumentList);
+    return null;
+  }
+  Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+    _writer.print("typedef ");
+    visit2(node.returnType, " ");
+    visit(node.name);
+    visit(node.typeParameters);
+    visit(node.parameters);
+    _writer.print(";");
+    return null;
+  }
+  Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    visit2(node.returnType, " ");
+    visit(node.identifier);
+    visit(node.parameters);
+    return null;
+  }
+  Object visitHideCombinator(HideCombinator node) {
+    _writer.print("hide ");
+    visitList2(node.hiddenNames, ", ");
+    return null;
+  }
+  Object visitIfStatement(IfStatement node) {
+    _writer.print("if (");
+    visit(node.condition);
+    _writer.print(") ");
+    visit(node.thenStatement);
+    visit3(" else ", node.elseStatement);
+    return null;
+  }
+  Object visitImplementsClause(ImplementsClause node) {
+    _writer.print("implements ");
+    visitList2(node.interfaces, ", ");
+    return null;
+  }
+  Object visitImportDirective(ImportDirective node) {
+    _writer.print("import ");
+    visit(node.libraryUri);
+    visit3(" as ", node.prefix);
+    visitList4(" ", node.combinators, " ");
+    _writer.print(';');
+    return null;
+  }
+  Object visitIndexExpression(IndexExpression node) {
+    if (node.isCascaded()) {
+      _writer.print("..");
+    } else {
+      visit(node.array);
+    }
+    _writer.print('[');
+    visit(node.index);
+    _writer.print(']');
+    return null;
+  }
+  Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+    visit5(node.keyword, " ");
+    visit(node.constructorName);
+    visit(node.argumentList);
+    return null;
+  }
+  Object visitIntegerLiteral(IntegerLiteral node) {
+    _writer.print(node.literal.lexeme);
+    return null;
+  }
+  Object visitInterpolationExpression(InterpolationExpression node) {
+    if (node.rightBracket != null) {
+      _writer.print("\${");
+      visit(node.expression);
+      _writer.print("}");
+    } else {
+      _writer.print("\$");
+      visit(node.expression);
+    }
+    return null;
+  }
+  Object visitInterpolationString(InterpolationString node) {
+    _writer.print(node.contents.lexeme);
+    return null;
+  }
+  Object visitIsExpression(IsExpression node) {
+    visit(node.expression);
+    if (node.notOperator == null) {
+      _writer.print(" is ");
+    } else {
+      _writer.print(" is! ");
+    }
+    visit(node.type);
+    return null;
+  }
+  Object visitLabel(Label node) {
+    visit(node.label);
+    _writer.print(":");
+    return null;
+  }
+  Object visitLabeledStatement(LabeledStatement node) {
+    visitList3(node.labels, " ", " ");
+    visit(node.statement);
+    return null;
+  }
+  Object visitLibraryDirective(LibraryDirective node) {
+    _writer.print("library ");
+    visit(node.name);
+    _writer.print(';');
+    return null;
+  }
+  Object visitLibraryIdentifier(LibraryIdentifier node) {
+    _writer.print(node.name);
+    return null;
+  }
+  Object visitListLiteral(ListLiteral node) {
+    if (node.modifier != null) {
+      _writer.print(node.modifier.lexeme);
+      _writer.print(' ');
+    }
+    visit2(node.typeArguments, " ");
+    _writer.print("[");
+    visitList2(node.elements, ", ");
+    _writer.print("]");
+    return null;
+  }
+  Object visitMapLiteral(MapLiteral node) {
+    if (node.modifier != null) {
+      _writer.print(node.modifier.lexeme);
+      _writer.print(' ');
+    }
+    visit2(node.typeArguments, " ");
+    _writer.print("{");
+    visitList2(node.entries, ", ");
+    _writer.print("}");
+    return null;
+  }
+  Object visitMapLiteralEntry(MapLiteralEntry node) {
+    visit(node.key);
+    _writer.print(" : ");
+    visit(node.value);
+    return null;
+  }
+  Object visitMethodDeclaration(MethodDeclaration node) {
+    visit5(node.externalKeyword, " ");
+    visit5(node.modifierKeyword, " ");
+    visit2(node.returnType, " ");
+    visit5(node.propertyKeyword, " ");
+    visit5(node.operatorKeyword, " ");
+    visit(node.name);
+    if (!node.isGetter()) {
+      visit(node.parameters);
+    }
+    visit4(" ", node.body);
+    return null;
+  }
+  Object visitMethodInvocation(MethodInvocation node) {
+    if (node.isCascaded()) {
+      _writer.print("..");
+    } else {
+      visit2(node.target, ".");
+    }
+    visit(node.methodName);
+    visit(node.argumentList);
+    return null;
+  }
+  Object visitNamedExpression(NamedExpression node) {
+    visit(node.name);
+    visit3(" ", node.expression);
+    return null;
+  }
+  Object visitNullLiteral(NullLiteral node) {
+    _writer.print("null");
+    return null;
+  }
+  Object visitParenthesizedExpression(ParenthesizedExpression node) {
+    _writer.print('(');
+    visit(node.expression);
+    _writer.print(')');
+    return null;
+  }
+  Object visitPartDirective(PartDirective node) {
+    _writer.print("part ");
+    visit(node.partUri);
+    _writer.print(';');
+    return null;
+  }
+  Object visitPartOfDirective(PartOfDirective node) {
+    _writer.print("part of ");
+    visit(node.libraryName);
+    _writer.print(';');
+    return null;
+  }
+  Object visitPostfixExpression(PostfixExpression node) {
+    visit(node.operand);
+    _writer.print(node.operator.lexeme);
+    return null;
+  }
+  Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+    visit(node.prefix);
+    _writer.print('.');
+    visit(node.identifier);
+    return null;
+  }
+  Object visitPrefixExpression(PrefixExpression node) {
+    _writer.print(node.operator.lexeme);
+    visit(node.operand);
+    return null;
+  }
+  Object visitPropertyAccess(PropertyAccess node) {
+    if (node.isCascaded()) {
+      _writer.print("..");
+    } else {
+      visit(node.target);
+      _writer.print('.');
+    }
+    visit(node.propertyName);
+    return null;
+  }
+  Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
+    _writer.print("this");
+    visit3(".", node.constructorName);
+    visit(node.argumentList);
+    return null;
+  }
+  Object visitReturnStatement(ReturnStatement node) {
+    Expression expression14 = node.expression;
+    if (expression14 == null) {
+      _writer.print("return;");
+    } else {
+      _writer.print("return ");
+      expression14.accept(this);
+      _writer.print(";");
+    }
+    return null;
+  }
+  Object visitScriptTag(ScriptTag node) {
+    _writer.print(node.scriptTag.lexeme);
+    return null;
+  }
+  Object visitShowCombinator(ShowCombinator node) {
+    _writer.print("show ");
+    visitList2(node.shownNames, ", ");
+    return null;
+  }
+  Object visitSimpleFormalParameter(SimpleFormalParameter node) {
+    visit5(node.keyword, " ");
+    visit2(node.type, " ");
+    visit(node.identifier);
+    return null;
+  }
+  Object visitSimpleIdentifier(SimpleIdentifier node) {
+    _writer.print(node.token.lexeme);
+    return null;
+  }
+  Object visitSimpleStringLiteral(SimpleStringLiteral node) {
+    _writer.print(node.literal.lexeme);
+    return null;
+  }
+  Object visitStringInterpolation(StringInterpolation node) {
+    visitList(node.elements);
+    return null;
+  }
+  Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    _writer.print("super");
+    visit3(".", node.constructorName);
+    visit(node.argumentList);
+    return null;
+  }
+  Object visitSuperExpression(SuperExpression node) {
+    _writer.print("super");
+    return null;
+  }
+  Object visitSwitchCase(SwitchCase node) {
+    visitList3(node.labels, " ", " ");
+    _writer.print("case ");
+    visit(node.expression);
+    _writer.print(": ");
+    visitList2(node.statements, " ");
+    return null;
+  }
+  Object visitSwitchDefault(SwitchDefault node) {
+    visitList3(node.labels, " ", " ");
+    _writer.print("default: ");
+    visitList2(node.statements, " ");
+    return null;
+  }
+  Object visitSwitchStatement(SwitchStatement node) {
+    _writer.print("switch (");
+    visit(node.expression);
+    _writer.print(") {");
+    visitList2(node.members, " ");
+    _writer.print("}");
+    return null;
+  }
+  Object visitThisExpression(ThisExpression node) {
+    _writer.print("this");
+    return null;
+  }
+  Object visitThrowExpression(ThrowExpression node) {
+    _writer.print("throw ");
+    visit(node.expression);
+    return null;
+  }
+  Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    visit2(node.variables, ";");
+    return null;
+  }
+  Object visitTryStatement(TryStatement node) {
+    _writer.print("try ");
+    visit(node.body);
+    visitList4(" ", node.catchClauses, " ");
+    visit3(" finally ", node.finallyClause);
+    return null;
+  }
+  Object visitTypeArgumentList(TypeArgumentList node) {
+    _writer.print('<');
+    visitList2(node.arguments, ", ");
+    _writer.print('>');
+    return null;
+  }
+  Object visitTypeName(TypeName node) {
+    visit(node.name);
+    visit(node.typeArguments);
+    return null;
+  }
+  Object visitTypeParameter(TypeParameter node) {
+    visit(node.name);
+    visit3(" extends ", node.bound);
+    return null;
+  }
+  Object visitTypeParameterList(TypeParameterList node) {
+    _writer.print('<');
+    visitList2(node.typeParameters, ", ");
+    _writer.print('>');
+    return null;
+  }
+  Object visitVariableDeclaration(VariableDeclaration node) {
+    visit(node.name);
+    visit3(" = ", node.initializer);
+    return null;
+  }
+  Object visitVariableDeclarationList(VariableDeclarationList node) {
+    visit5(node.keyword, " ");
+    visit2(node.type, " ");
+    visitList2(node.variables, ", ");
+    return null;
+  }
+  Object visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    visit(node.variables);
+    _writer.print(";");
+    return null;
+  }
+  Object visitWhileStatement(WhileStatement node) {
+    _writer.print("while (");
+    visit(node.condition);
+    _writer.print(") ");
+    visit(node.body);
+    return null;
+  }
+  Object visitWithClause(WithClause node) {
+    _writer.print("with ");
+    visitList2(node.mixinTypes, ", ");
+    return null;
+  }
+  /**
+   * Safely visit the given node.
+   * @param node the node to be visited
+   */
+  void visit(ASTNode node) {
+    if (node != null) {
+      node.accept(this);
+    }
+  }
+  /**
+   * Safely visit the given node, printing the suffix after the node if it is non-{@code null}.
+   * @param suffix the suffix to be printed if there is a node to visit
+   * @param node the node to be visited
+   */
+  void visit2(ASTNode node, String suffix) {
+    if (node != null) {
+      node.accept(this);
+      _writer.print(suffix);
+    }
+  }
+  /**
+   * Safely visit the given node, printing the prefix before the node if it is non-{@code null}.
+   * @param prefix the prefix to be printed if there is a node to visit
+   * @param node the node to be visited
+   */
+  void visit3(String prefix, ASTNode node) {
+    if (node != null) {
+      _writer.print(prefix);
+      node.accept(this);
+    }
+  }
+  /**
+   * Visit the given function body, printing the prefix before if given body is not empty.
+   * @param prefix the prefix to be printed if there is a node to visit
+   * @param body the function body to be visited
+   */
+  void visit4(String prefix, FunctionBody body) {
+    if (body is! EmptyFunctionBody) {
+      _writer.print(prefix);
+    }
+    visit(body);
+  }
+  /**
+   * Safely visit the given node, printing the suffix after the node if it is non-{@code null}.
+   * @param suffix the suffix to be printed if there is a node to visit
+   * @param node the node to be visited
+   */
+  void visit5(Token token, String suffix) {
+    if (token != null) {
+      _writer.print(token.lexeme);
+      _writer.print(suffix);
+    }
+  }
+  /**
+   * Print a list of nodes without any separation.
+   * @param nodes the nodes to be printed
+   * @param separator the separator to be printed between adjacent nodes
+   */
+  void visitList(NodeList<ASTNode> nodes) {
+    visitList2(nodes, "");
+  }
+  /**
+   * Print a list of nodes, separated by the given separator.
+   * @param nodes the nodes to be printed
+   * @param separator the separator to be printed between adjacent nodes
+   */
+  void visitList2(NodeList<ASTNode> nodes, String separator) {
+    if (nodes != null) {
+      int size3 = nodes.length;
+      for (int i = 0; i < size3; i++) {
+        if (i > 0) {
+          _writer.print(separator);
+        }
+        nodes[i].accept(this);
+      }
+    }
+  }
+  /**
+   * Print a list of nodes, separated by the given separator.
+   * @param nodes the nodes to be printed
+   * @param separator the separator to be printed between adjacent nodes
+   * @param suffix the suffix to be printed if the list is not empty
+   */
+  void visitList3(NodeList<ASTNode> nodes, String separator, String suffix) {
+    if (nodes != null) {
+      int size4 = nodes.length;
+      if (size4 > 0) {
+        for (int i = 0; i < size4; i++) {
+          if (i > 0) {
+            _writer.print(separator);
+          }
+          nodes[i].accept(this);
+        }
+        _writer.print(suffix);
+      }
+    }
+  }
+  /**
+   * Print a list of nodes, separated by the given separator.
+   * @param prefix the prefix to be printed if the list is not empty
+   * @param nodes the nodes to be printed
+   * @param separator the separator to be printed between adjacent nodes
+   */
+  void visitList4(String prefix, NodeList<ASTNode> nodes, String separator) {
+    if (nodes != null) {
+      int size5 = nodes.length;
+      if (size5 > 0) {
+        _writer.print(prefix);
+        for (int i = 0; i < size5; i++) {
+          if (i > 0) {
+            _writer.print(separator);
+          }
+          nodes[i].accept(this);
+        }
+      }
+    }
+  }
+}
+/**
+ * Instances of the class {@code NodeList} represent a list of AST nodes that have a common parent.
+ */
+class NodeList<E extends ASTNode> extends ListWrapper<E> {
+  /**
+   * The node that is the parent of each of the elements in the list.
+   */
+  ASTNode owner;
+  /**
+   * The elements of the list.
+   */
+  List<E> elements = new List<E>();
+  /**
+   * Initialize a newly created list of nodes to be empty.
+   * @param owner the node that is the parent of each of the elements in the list
+   */
+  NodeList(ASTNode this.owner);
+  /**
+   * Use the given visitor to visit each of the nodes in this list.
+   * @param visitor the visitor to be used to visit the elements of this list
+   */
+  accept(ASTVisitor visitor) {
+    for (E element in elements) {
+      element.accept(visitor);
+    }
+  }
+  void add(E node) {
+    owner.becomeParentOf(node);
+    elements.add(node);
+  }
+  bool addAll(Collection<E> nodes) {
+    if (nodes != null) {
+      super.addAll(nodes);
+      return true;
+    }
+    return false;
+  }
+  /**
+   * Return the first token included in this node's source range.
+   * @return the first token included in this node's source range
+   */
+  Token get beginToken {
+    if (elements.isEmpty) {
+      return null;
+    }
+    return elements[0].beginToken;
+  }
+  /**
+   * Return the last token included in this node list's source range.
+   * @return the last token included in this node list's source range
+   */
+  Token get endToken {
+    if (elements.isEmpty) {
+      return null;
+    }
+    return elements[elements.length - 1].endToken;
+  }
+  /**
+   * Return the node that is the parent of each of the elements in the list.
+   * @return the node that is the parent of each of the elements in the list
+   */
+  ASTNode getOwner() {
+    return owner;
+  }
+}
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/lib/src/generated/element.dart b/pkg/analyzer-experimental/lib/src/generated/element.dart
new file mode 100644
index 0000000..2a4af3f
--- /dev/null
+++ b/pkg/analyzer-experimental/lib/src/generated/element.dart
@@ -0,0 +1,3344 @@
+// 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;
+
+import 'dart:collection';
+import 'java_core.dart';
+import 'java_engine.dart';
+import 'source.dart';
+import 'scanner.dart' show Keyword;
+import 'ast.dart';
+import 'package:analyzer-experimental/src/generated/utilities_dart.dart';
+
+/**
+ * The interface {@code Annotation} defines the behavior of objects representing a single annotation
+ * associated with an element.
+ */
+abstract class Annotation {
+  /**
+   * Return the element representing the field, variable, or const constructor being used as an
+   * annotation.
+   * @return the field, variable, or constructor being used as an annotation
+   */
+  Element get element;
+}
+/**
+ * The interface {@code ClassElement} defines the behavior of elements that represent a class.
+ */
+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
+   */
+  List<PropertyAccessorElement> get accessors;
+  /**
+   * Return an array containing all of the constructors contained in this class.
+   * @return the constructors contained 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
+   */
+  List<FieldElement> get fields;
+  /**
+   * Return an array containing all of the interfaces that are implemented by this class.
+   * @return the interfaces that are implemented by this class
+   */
+  List<InterfaceType> get interfaces;
+  /**
+   * Return an array containing all of the methods contained in this class.
+   * @return the methods contained in this class
+   */
+  List<MethodElement> get methods;
+  /**
+   * Return an array containing all of the mixins that are applied to the class being extended in
+   * order to derive the superclass of this class.
+   * @return the mixins that are applied to derive the superclass of this class
+   */
+  List<InterfaceType> get mixins;
+  /**
+   * 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.
+   * @return the superclass of this class
+   */
+  InterfaceType get supertype;
+  /**
+   * Return the type defined by the class.
+   * @return the type defined by the class
+   */
+  InterfaceType get type;
+  /**
+   * Return an array containing all of the type variables defined for this class.
+   * @return the type variables defined for this class
+   */
+  List<TypeVariableElement> get typeVariables;
+  /**
+   * 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();
+}
+/**
+ * The interface {@code CompilationUnitElement} defines the behavior of elements representing a
+ * compilation unit.
+ */
+abstract class CompilationUnitElement implements Element {
+  /**
+   * Return an array containing all of the top-level accessors (getters and setters) contained in
+   * this compilation unit.
+   * @return the top-level accessors contained in this compilation unit
+   */
+  List<PropertyAccessorElement> get accessors;
+  /**
+   * Return the library in which this compilation unit is defined.
+   * @return the library in which this compilation unit is defined
+   */
+  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
+   */
+  List<TypeAliasElement> get typeAliases;
+  /**
+   * Return an array containing all of the classes contained in this compilation unit.
+   * @return the classes contained in this compilation unit
+   */
+  List<ClassElement> get types;
+}
+/**
+ * The interface {@code ConstructorElement} defines the behavior of elements representing a
+ * constructor or a factory method defined within a type.
+ */
+abstract class ConstructorElement implements ExecutableElement {
+  /**
+   * Return the type in which this constructor is defined.
+   * @return the type in which this constructor is defined
+   */
+  ClassElement get enclosingElement;
+  /**
+   * Return {@code true} if this constructor is a const constructor.
+   * @return {@code true} if this constructor is a const constructor
+   */
+  bool isConst();
+  /**
+   * Return {@code true} if this constructor represents a factory constructor.
+   * @return {@code true} if this constructor represents a factory constructor
+   */
+  bool isFactory();
+}
+/**
+ * The interface {@code Element} defines the behavior common to all of the elements in the element
+ * model. Generally speaking, the element model is a semantic model of the program that represents
+ * things that are declared with a name and hence can be referenced elsewhere in the code.
+ * <p>
+ * There are two exceptions to the general case. First, there are elements in the element model that
+ * are created for the convenience of various kinds of analysis but that do not have any
+ * corresponding declaration within the source code. Such elements are marked as being
+ * <i>synthetic</i>. Examples of synthetic elements include
+ * <ul>
+ * <li>default constructors in classes that do not define any explicit constructors,
+ * <li>getters and setters that are induced by explicit field declarations,
+ * <li>fields that are induced by explicit declarations of getters and setters, and
+ * <li>functions representing the initialization expression for a variable.
+ * </ul>
+ * <p>
+ * Second, there are elements in the element model that do not have a name. These correspond to
+ * unnamed functions and exist in order to more accurately represent the semantic structure of the
+ * program.
+ */
+abstract class Element {
+  /**
+   * Return the element of the given class that most immediately encloses this element, or{@code null} if there is no enclosing element of the given class.
+   * @param elementClass the class of the element to be returned
+   * @return the element that encloses this element
+   */
+  Element getAncestor(Type elementClass);
+  /**
+   * Return the analysis context in which this element is defined.
+   * @return the analysis context in which this element is defined
+   */
+  AnalysisContext get context;
+  /**
+   * Return the element that either physically or logically encloses this element. This will be{@code null} if this element is a library because libraries are the top-level elements in the
+   * model.
+   * @return the element that encloses this element
+   */
+  Element get enclosingElement;
+  /**
+   * Return the kind of element that this is.
+   * @return the kind of this element
+   */
+  ElementKind get kind;
+  /**
+   * Return the library that contains this element. This will be {@code null} if this element is a
+   * library or HTML file because libraries and HTML files are not contained in other libraries.
+   * @return the library that contains this element
+   */
+  LibraryElement get library;
+  /**
+   * Return an object representing the location of this element in the element model. The object can
+   * be used to locate this element at a later time.
+   * @return the location of this element in the element model
+   */
+  ElementLocation get location;
+  /**
+   * Return an array containing all of the metadata associated with this element.
+   * @return the metadata associated with this element
+   */
+  List<Annotation> get metadata;
+  /**
+   * Return the name of this element, or {@code null} if this element does not have a name.
+   * @return the name of this element
+   */
+  String get name;
+  /**
+   * Return the offset of the name of this element in the file that contains the declaration of this
+   * element, or {@code -1} if this element is synthetic, does not have a name, or otherwise does
+   * not have an offset.
+   * @return the offset of the name of this element
+   */
+  int get nameOffset;
+  /**
+   * 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.
+   * @return {@code true} if this element is synthetic
+   */
+  bool isSynthetic();
+}
+/**
+ * The enumeration {@code ElementKind} defines the various kinds of elements in the element model.
+ */
+class ElementKind {
+  static final ElementKind CLASS = new ElementKind('CLASS', 0);
+  static final ElementKind COMPILATION_UNIT = new ElementKind('COMPILATION_UNIT', 1);
+  static final ElementKind CONSTRUCTOR = new ElementKind('CONSTRUCTOR', 2);
+  static final ElementKind DYNAMIC = new ElementKind('DYNAMIC', 3);
+  static final ElementKind ERROR = new ElementKind('ERROR', 4);
+  static final ElementKind EXPORT = new ElementKind('EXPORT', 5);
+  static final ElementKind FIELD = new ElementKind('FIELD', 6);
+  static final ElementKind FUNCTION = new ElementKind('FUNCTION', 7);
+  static final ElementKind GETTER = new ElementKind('GETTER', 8);
+  static final ElementKind HTML = new ElementKind('HTML', 9);
+  static final ElementKind IMPORT = new ElementKind('IMPORT', 10);
+  static final ElementKind LABEL = new ElementKind('LABEL', 11);
+  static final ElementKind LIBRARY = new ElementKind('LIBRARY', 12);
+  static final ElementKind METHOD = new ElementKind('METHOD', 13);
+  static final ElementKind NAME = new ElementKind('NAME', 14);
+  static final ElementKind PARAMETER = new ElementKind('PARAMETER', 15);
+  static final ElementKind PREFIX = new ElementKind('PREFIX', 16);
+  static final ElementKind SETTER = new ElementKind('SETTER', 17);
+  static final ElementKind TYPE_ALIAS = new ElementKind('TYPE_ALIAS', 18);
+  static final ElementKind TYPE_VARIABLE = new ElementKind('TYPE_VARIABLE', 19);
+  static final ElementKind UNIVERSE = new ElementKind('UNIVERSE', 20);
+  static final ElementKind VARIABLE = new ElementKind('VARIABLE', 21);
+  static final List<ElementKind> values = [CLASS, COMPILATION_UNIT, CONSTRUCTOR, DYNAMIC, ERROR, EXPORT, FIELD, FUNCTION, GETTER, HTML, IMPORT, LABEL, LIBRARY, METHOD, NAME, PARAMETER, PREFIX, SETTER, TYPE_ALIAS, TYPE_VARIABLE, UNIVERSE, VARIABLE];
+  final String __name;
+  final int __ordinal;
+  ElementKind(this.__name, this.__ordinal) {
+  }
+  String toString() => __name;
+}
+/**
+ * The interface {@code ElementLocation} defines the behavior of objects that represent the location
+ * of an element within the element model.
+ */
+abstract class ElementLocation {
+  /**
+   * Return an encoded representation of this location that can be used to create a location that is
+   * equal to this location.
+   * @return an encoded representation of this location
+   */
+  String get encoding;
+}
+/**
+ * The interface {@code ExecutableElement} defines the behavior of elements representing an
+ * executable object, including functions, methods, constructors, getters, and setters.
+ */
+abstract class ExecutableElement implements Element {
+  /**
+   * Return an array containing all of the functions defined within this executable element.
+   * @return the functions defined within this executable element
+   */
+  List<ExecutableElement> get functions;
+  /**
+   * Return an array containing all of the labels defined within this executable element.
+   * @return the labels defined within this executable element
+   */
+  List<LabelElement> get labels;
+  /**
+   * Return an array containing all of the local variables defined within this executable element.
+   * @return the local variables defined within this executable element
+   */
+  List<VariableElement> get localVariables;
+  /**
+   * Return an array containing all of the parameters defined by this executable element.
+   * @return the parameters defined by this executable element
+   */
+  List<ParameterElement> get parameters;
+  /**
+   * Return the type of function defined by this executable element.
+   * @return the type of function defined by this executable element
+   */
+  FunctionType get type;
+}
+/**
+ * The interface {@code ExportElement} defines the behavior of objects representing information
+ * about a single export directive within a library.
+ */
+abstract class ExportElement implements Element {
+  /**
+   * An empty array of export elements.
+   */
+  static List<ExportElement> EMPTY_ARRAY = new List<ExportElement>.fixedLength(0);
+  /**
+   * Return an array containing the combinators that were specified as part of the export directive
+   * in the order in which they were specified.
+   * @return the combinators specified in the export directive
+   */
+  List<NamespaceCombinator> get combinators;
+  /**
+   * Return the library that is exported from this library by this export directive.
+   * @return the library that is exported from this library
+   */
+  LibraryElement get exportedLibrary;
+}
+/**
+ * The interface {@code FieldElement} defines the behavior of elements representing a field defined
+ * within a type. Note that explicitly defined fields implicitly define a synthetic getter and that
+ * non-{@code final} explicitly defined fields implicitly define a synthetic setter. Symmetrically,
+ * synthetic fields are implicitly created for explicitly defined getters and setters. The following
+ * rules apply:
+ * <ul>
+ * <li>Every explicit field is represented by a non-synthetic {@link FieldElement}.
+ * <li>Every explicit field induces a getter and possibly a setter, both of which are represented by
+ * synthetic {@link PropertyAccessorElement}s.
+ * <li>Every explicit getter or setter is represented by a non-synthetic{@link PropertyAccessorElement}.
+ * <li>Every explicit getter or setter (or pair thereof if they have the same name) induces a field
+ * that is represented by a synthetic {@link FieldElement}.
+ * </ul>
+ */
+abstract class FieldElement implements VariableElement {
+  /**
+   * Return the getter associated with this field. If this field was explicitly defined (is not
+   * synthetic) then the getter associated with it will be synthetic.
+   * @return the getter associated with this field
+   */
+  PropertyAccessorElement get getter;
+  /**
+   * Return the setter associated with this field, or {@code null} if the field is effectively{@code final} and therefore does not have a setter associated with it. (This can happen either
+   * because the field is explicitly defined as being {@code final} or because the field is induced
+   * by an explicit getter that does not have a corresponding setter.) If this field was explicitly
+   * defined (is not synthetic) then the setter associated with it will be synthetic.
+   * @return the setter associated with this field
+   */
+  PropertyAccessorElement get setter;
+  /**
+   * Return {@code true} if this field is a static field.
+   * @return {@code true} if this field is a static field
+   */
+  bool isStatic();
+}
+/**
+ * The interface {@code FunctionElement} defines the behavior of elements representing a function.
+ */
+abstract class FunctionElement implements ExecutableElement {
+}
+/**
+ * The interface {@code HideCombinator} defines the behavior of combinators that cause some of the
+ * names in a namespace to be hidden when being imported.
+ */
+abstract class HideCombinator implements NamespaceCombinator {
+  /**
+   * Return an array containing the names that are not to be made visible in the importing library
+   * even if they are defined in the imported library.
+   * @return the names from the imported library that are hidden from the importing library
+   */
+  List<String> get hiddenNames;
+}
+/**
+ * The interface {@code HtmlElement} defines the behavior of elements representing an HTML file.
+ */
+abstract class HtmlElement implements Element {
+  /**
+   * Return an array containing all of the libraries contained in or referenced from script tags in
+   * the HTML file. This includes libraries that are defined by the content of a script file as well
+   * as libraries that are referenced in the {@core src} attribute of a script tag.
+   * @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
+ * about a single import directive within a library.
+ */
+abstract class ImportElement implements Element {
+  /**
+   * An empty array of import elements.
+   */
+  static List<ImportElement> EMPTY_ARRAY = new List<ImportElement>.fixedLength(0);
+  /**
+   * Return an array containing the combinators that were specified as part of the import directive
+   * in the order in which they were specified.
+   * @return the combinators specified in the import directive
+   */
+  List<NamespaceCombinator> get combinators;
+  /**
+   * Return the library that is imported into this library by this import directive.
+   * @return the library that is imported into this library
+   */
+  LibraryElement get importedLibrary;
+  /**
+   * Return the prefix that was specified as part of the import directive, or {@code null} if there
+   * was no prefix specified.
+   * @return the prefix that was specified as part of the import directive
+   */
+  PrefixElement get prefix;
+}
+/**
+ * The interface {@code LabelElement} defines the behavior of elements representing a label
+ * associated with a statement.
+ */
+abstract class LabelElement implements Element {
+  /**
+   * Return the executable element in which this label is defined.
+   * @return the executable element in which this label is defined
+   */
+  ExecutableElement get enclosingElement;
+}
+/**
+ * The interface {@code LibraryElement} defines the behavior of elements representing a library.
+ */
+abstract class LibraryElement implements Element {
+  /**
+   * Return the compilation unit that defines this library.
+   * @return the compilation unit that defines this library
+   */
+  CompilationUnitElement get definingCompilationUnit;
+  /**
+   * Return the entry point for this library, or {@code null} if this library does not have an entry
+   * point. The entry point is defined to be a zero argument top-level function whose name is{@code main}.
+   * @return the entry point for this library
+   */
+  FunctionElement get entryPoint;
+  /**
+   * Return an array containing all of the exports defined in this library.
+   * @return the exports defined in this library
+   */
+  List<ExportElement> get exports;
+  /**
+   * Return an array containing all of the libraries that are imported into this library. This
+   * includes all of the libraries that are imported using a prefix (also available through the
+   * prefixes returned by {@link #getPrefixes()}) and those that are imported without a prefix.
+   * @return an array containing all of the libraries that are imported into this library
+   */
+  List<LibraryElement> get importedLibraries;
+  /**
+   * Return an array containing all of the imports defined in this library.
+   * @return the imports defined in this library
+   */
+  List<ImportElement> get imports;
+  /**
+   * Return an array containing all of the compilation units that are included in this library using
+   * a {@code part} directive. This does not include the defining compilation unit that contains the{@code part} directives.
+   * @return the compilation units that are included in this library
+   */
+  List<CompilationUnitElement> get parts;
+  /**
+   * Return an array containing elements for each of the prefixes used to {@code import} libraries
+   * into this library. Each prefix can be used in more than one {@code import} directive.
+   * @return the prefixes used to {@code import} libraries into this library
+   */
+  List<PrefixElement> get prefixes;
+}
+/**
+ * The interface {@code MethodElement} defines the behavior of elements that represent a method
+ * defined within a type.
+ */
+abstract class MethodElement implements ExecutableElement {
+  /**
+   * Return the type in which this method is defined.
+   * @return the type in which this method is defined
+   */
+  ClassElement get enclosingElement;
+  /**
+   * Return {@code true} if this method is abstract. Methods are abstract if they are not external
+   * and have no body.
+   * @return {@code true} if this method is abstract
+   */
+  bool isAbstract();
+  /**
+   * Return {@code true} if this method is static. Methods are static if they have been marked as
+   * being static using the {@code static} modifier.
+   * @return {@code true} if this method is static
+   */
+  bool isStatic();
+}
+/**
+ * The interface {@code MultiplyDefinedElement} defines the behavior of pseudo-elements that
+ * represent multiple elements defined within a single scope that have the same name. This situation
+ * is not allowed by the language, so objects implementing this interface always represent an error.
+ * As a result, most of the normal operations on elements do not make sense and will return useless
+ * results.
+ */
+abstract class MultiplyDefinedElement implements Element {
+  /**
+   * Return an array containing all of the elements that were defined within the scope to have the
+   * same name.
+   * @return the elements that were defined with the same name
+   */
+  List<Element> get conflictingElements;
+}
+/**
+ * The interface {@code NamespaceCombinator} defines the behavior common to objects that control how
+ * namespaces are combined.
+ */
+abstract class NamespaceCombinator {
+  /**
+   * An empty array of namespace combinators.
+   */
+  static List<NamespaceCombinator> EMPTY_ARRAY = new List<NamespaceCombinator>.fixedLength(0);
+}
+/**
+ * The interface {@code ParameterElement} defines the behavior of elements representing a parameter
+ * defined within an executable element.
+ */
+abstract class ParameterElement implements VariableElement {
+  /**
+   * Return the kind of this parameter.
+   * @return the kind of this parameter
+   */
+  ParameterKind get parameterKind;
+}
+/**
+ * The interface {@code PrefixElement} defines the behavior common to elements that represent a
+ * prefix used to import one or more libraries into another library.
+ */
+abstract class PrefixElement implements Element {
+  /**
+   * Return the library into which other libraries are imported using this prefix.
+   * @return the library into which other libraries are imported using this prefix
+   */
+  LibraryElement get enclosingElement;
+  /**
+   * Return an array containing all of the libraries that are imported using this prefix.
+   * @return the libraries that are imported using this prefix
+   */
+  List<LibraryElement> get importedLibraries;
+}
+/**
+ * The interface {@code PropertyAccessorElement} defines the behavior of elements representing a
+ * getter or a setter. Note that explicitly defined property accessors implicitly define a synthetic
+ * field. Symmetrically, synthetic accessors are implicitly created for explicitly defined fields.
+ * The following rules apply:
+ * <ul>
+ * <li>Every explicit field is represented by a non-synthetic {@link FieldElement}.
+ * <li>Every explicit field induces a getter and possibly a setter, both of which are represented by
+ * synthetic {@link PropertyAccessorElement}s.
+ * <li>Every explicit getter or setter is represented by a non-synthetic{@link PropertyAccessorElement}.
+ * <li>Every explicit getter or setter (or pair thereof if they have the same name) induces a field
+ * that is represented by a synthetic {@link FieldElement}.
+ * </ul>
+ */
+abstract class PropertyAccessorElement implements ExecutableElement {
+  /**
+   * Return the field associated with this accessor. If this accessor was explicitly defined (is not
+   * synthetic) then the field associated with it will be synthetic.
+   * @return the field associated with this accessor
+   */
+  FieldElement get field;
+  /**
+   * Return {@code true} if this accessor represents a getter.
+   * @return {@code true} if this accessor represents a getter
+   */
+  bool isGetter();
+  /**
+   * Return {@code true} if this accessor represents a setter.
+   * @return {@code true} if this accessor represents a setter
+   */
+  bool isSetter();
+}
+/**
+ * The interface {@code ShowCombinator} defines the behavior of combinators that cause some of the
+ * names in a namespace to be visible (and the rest hidden) when being imported.
+ */
+abstract class ShowCombinator implements NamespaceCombinator {
+  /**
+   * Return an array containing the names that are to be made visible in the importing library if
+   * they are defined in the imported library.
+   * @return the names from the imported library that are visible in the importing library
+   */
+  List<String> get shownNames;
+}
+/**
+ * The interface {@code TypeAliasElement} defines the behavior of elements representing a type alias
+ * ({@code typedef}).
+ */
+abstract class TypeAliasElement implements Element {
+  /**
+   * Return the compilation unit in which this type alias is defined.
+   * @return the compilation unit in which this type alias is defined
+   */
+  CompilationUnitElement get enclosingElement;
+  /**
+   * Return an array containing all of the parameters defined by this type alias.
+   * @return the parameters defined by this type alias
+   */
+  List<ParameterElement> get parameters;
+  /**
+   * Return the type of function defined by this type alias.
+   * @return the type of function defined by this type alias
+   */
+  FunctionType get type;
+  /**
+   * Return an array containing all of the type variables defined for this type.
+   * @return the type variables defined for this type
+   */
+  List<TypeVariableElement> get typeVariables;
+}
+/**
+ * The interface {@code TypeVariableElement} defines the behavior of elements representing a type
+ * variable.
+ */
+abstract class TypeVariableElement implements Element {
+  /**
+   * Return the type representing the bound associated with this variable, or {@code null} if this
+   * variable does not have an explicit bound.
+   * @return the type representing the bound associated with this variable
+   */
+  Type2 get bound;
+  /**
+   * Return the type defined by this type variable.
+   * @return the type defined by this type variable
+   */
+  TypeVariableType get type;
+}
+/**
+ * The interface {@code UndefinedElement} defines the behavior of pseudo-elements that represent
+ * names that are undefined. This situation is not allowed by the language, so objects implementing
+ * this interface always represent an error. As a result, most of the normal operations on elements
+ * do not make sense and will return useless results.
+ */
+abstract class UndefinedElement implements Element {
+}
+/**
+ * The interface {@code VariableElement} defines the behavior common to elements that represent a
+ * variable.
+ */
+abstract class VariableElement implements Element {
+  /**
+   * Return a synthetic function representing this variable's initializer, or {@code null} if this
+   * variable does not have an initializer. The function will have no parameters. The return type of
+   * the function will be the compile-time type of the initialization expression.
+   * @return a synthetic function representing this variable's initializer
+   */
+  FunctionElement get initializer;
+  /**
+   * Return the declared type of this variable, or {@code null} if the variable did not have a
+   * declared type (such as if it was declared using the keyword 'var').
+   * @return the declared type of this variable
+   */
+  Type2 get type;
+  /**
+   * 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
+   */
+  bool isConst();
+  /**
+   * Return {@code true} if this variable is a final variable. Variables are final if they have been
+   * marked as being final using either the {@code final} or {@code const} modifiers.
+   * @return {@code true} if this variable is a final variable
+   */
+  bool isFinal();
+}
+/**
+ * Instances of the class {@code AnnotationImpl} implement an {@link Annotation}.
+ */
+class AnnotationImpl implements Annotation {
+  /**
+   * The element representing the field, variable, or constructor being used as an annotation.
+   */
+  Element _element;
+  /**
+   * An empty array of annotations.
+   */
+  static List<AnnotationImpl> EMPTY_ARRAY = new List<AnnotationImpl>.fixedLength(0);
+  /**
+   * Initialize a newly created annotation.
+   * @param element the element representing the field, variable, or constructor being used as an
+   * annotation
+   */
+  AnnotationImpl(Element element) {
+    this._element = element;
+  }
+  Element get element => _element;
+}
+/**
+ * Instances of the class {@code ClassElementImpl} implement a {@code ClassElement}.
+ */
+class ClassElementImpl extends ElementImpl implements ClassElement {
+  /**
+   * An array containing all of the accessors (getters and setters) contained in this class.
+   */
+  List<PropertyAccessorElement> _accessors = PropertyAccessorElementImpl.EMPTY_ARRAY;
+  /**
+   * An array containing all of the constructors contained in this class.
+   */
+  List<ConstructorElement> _constructors = ConstructorElementImpl.EMPTY_ARRAY;
+  /**
+   * An array containing all of the fields contained in this class.
+   */
+  List<FieldElement> _fields = FieldElementImpl.EMPTY_ARRAY;
+  /**
+   * An array containing all of the mixins that are applied to the class being extended in order to
+   * derive the superclass of this class.
+   */
+  List<InterfaceType> _mixins = InterfaceTypeImpl.EMPTY_ARRAY;
+  /**
+   * An array containing all of the interfaces that are implemented by this class.
+   */
+  List<InterfaceType> _interfaces = InterfaceTypeImpl.EMPTY_ARRAY;
+  /**
+   * An array containing all of the methods contained in this class.
+   */
+  List<MethodElement> _methods = MethodElementImpl.EMPTY_ARRAY;
+  /**
+   * The superclass of the class, or {@code null} if the class does not have an explicit superclass.
+   */
+  InterfaceType _supertype;
+  /**
+   * The type defined by the class.
+   */
+  InterfaceType _type;
+  /**
+   * An array containing all of the type variables defined for this class.
+   */
+  List<TypeVariableElement> _typeVariables = TypeVariableElementImpl.EMPTY_ARRAY;
+  /**
+   * An empty array of type elements.
+   */
+  static List<ClassElement> EMPTY_ARRAY = new List<ClassElement>.fixedLength(0);
+  /**
+   * Initialize a newly created class element to have the given name.
+   * @param name the name of this element
+   */
+  ClassElementImpl(Identifier name) : super.con1(name) {
+  }
+  List<PropertyAccessorElement> get accessors => _accessors;
+  ElementImpl getChild(String identifier) {
+    for (PropertyAccessorElement accessor in _accessors) {
+      if ((accessor as PropertyAccessorElementImpl).identifier == identifier) {
+        return accessor as PropertyAccessorElementImpl;
+      }
+    }
+    for (ConstructorElement constructor in _constructors) {
+      if ((constructor as ConstructorElementImpl).identifier == identifier) {
+        return constructor as ConstructorElementImpl;
+      }
+    }
+    for (FieldElement field in _fields) {
+      if ((field as FieldElementImpl).identifier == identifier) {
+        return field as FieldElementImpl;
+      }
+    }
+    for (MethodElement method in _methods) {
+      if ((method as MethodElementImpl).identifier == identifier) {
+        return method as MethodElementImpl;
+      }
+    }
+    for (TypeVariableElement typeVariable in _typeVariables) {
+      if ((typeVariable as TypeVariableElementImpl).identifier == identifier) {
+        return typeVariable as TypeVariableElementImpl;
+      }
+    }
+    return null;
+  }
+  List<ConstructorElement> get constructors => _constructors;
+  List<FieldElement> get fields => _fields;
+  List<InterfaceType> get interfaces => _interfaces;
+  ElementKind get kind => ElementKind.CLASS;
+  List<MethodElement> get methods => _methods;
+  List<InterfaceType> get mixins => _mixins;
+  InterfaceType get supertype => _supertype;
+  InterfaceType get type => _type;
+  List<TypeVariableElement> get typeVariables => _typeVariables;
+  bool isAbstract() => hasModifier(Modifier.ABSTRACT);
+  /**
+   * Set whether this class is abstract to correspond to the given value.
+   * @param isAbstract {@code true} if the class is abstract
+   */
+  void set abstract(bool isAbstract) {
+    setModifier(Modifier.ABSTRACT, isAbstract);
+  }
+  /**
+   * 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;
+    }
+    this._accessors = accessors;
+  }
+  /**
+   * 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;
+    }
+    this._constructors = constructors;
+  }
+  /**
+   * 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;
+    }
+    this._fields = fields;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+    }
+    this._methods = methods;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+    }
+    this._typeVariables = typeVariables;
+  }
+  String toString() {
+    String name15 = name;
+    return name15 == null ? "<unnamed class>" : "class ${name15}";
+  }
+}
+/**
+ * Instances of the class {@code CompilationUnitElementImpl} implement a{@link CompilationUnitElement}.
+ */
+class CompilationUnitElementImpl extends ElementImpl implements CompilationUnitElement {
+  /**
+   * An array containing all of the top-level accessors (getters and setters) contained in this
+   * compilation unit.
+   */
+  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;
+  /**
+   * The source that corresponds to this compilation unit.
+   */
+  Source _source;
+  /**
+   * An array containing all of the type aliases contained in this compilation unit.
+   */
+  List<TypeAliasElement> _typeAliases = TypeAliasElementImpl.EMPTY_ARRAY;
+  /**
+   * An array containing all of the types contained in this compilation unit.
+   */
+  List<ClassElement> _types = ClassElementImpl.EMPTY_ARRAY;
+  /**
+   * An empty array of compilation unit elements.
+   */
+  static List<CompilationUnitElement> EMPTY_ARRAY = new List<CompilationUnitElement>.fixedLength(0);
+  /**
+   * Initialize a newly created compilation unit element to have the given name.
+   * @param name the name of this element
+   */
+  CompilationUnitElementImpl(String name) : super.con2(name, -1) {
+  }
+  bool operator ==(Object object) => this.runtimeType == object.runtimeType && _source == (object as CompilationUnitElementImpl).source;
+  List<PropertyAccessorElement> get accessors => _accessors;
+  ElementImpl getChild(String identifier) {
+    for (PropertyAccessorElement accessor in _accessors) {
+      if ((accessor as PropertyAccessorElementImpl).identifier == identifier) {
+        return accessor as PropertyAccessorElementImpl;
+      }
+    }
+    for (FieldElement field in _fields) {
+      if ((field as FieldElementImpl).identifier == identifier) {
+        return field as FieldElementImpl;
+      }
+    }
+    for (ExecutableElement function in _functions) {
+      if ((function as ExecutableElementImpl).identifier == identifier) {
+        return function as ExecutableElementImpl;
+      }
+    }
+    for (TypeAliasElement typeAlias in _typeAliases) {
+      if ((typeAlias as TypeAliasElementImpl).identifier == identifier) {
+        return typeAlias as TypeAliasElementImpl;
+      }
+    }
+    for (ClassElement type in _types) {
+      if ((type as ClassElementImpl).identifier == identifier) {
+        return type as ClassElementImpl;
+      }
+    }
+    return null;
+  }
+  LibraryElement get enclosingElement => super.enclosingElement as LibraryElement;
+  List<FieldElement> get fields => _fields;
+  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;
+  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;
+    }
+    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;
+  }
+  /**
+   * 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;
+    }
+    this._functions = functions;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+    }
+    this._typeAliases = typeAliases;
+  }
+  /**
+   * 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;
+    }
+    this._types = types;
+  }
+}
+/**
+ * Instances of the class {@code ConstructorElementImpl} implement a {@code ConstructorElement}.
+ */
+class ConstructorElementImpl extends ExecutableElementImpl implements ConstructorElement {
+  /**
+   * An empty array of constructor elements.
+   */
+  static List<ConstructorElement> EMPTY_ARRAY = new List<ConstructorElement>.fixedLength(0);
+  /**
+   * Initialize a newly created constructor element to have the given name.
+   * @param name the name of this element
+   */
+  ConstructorElementImpl(Identifier name) : super.con1(name) {
+  }
+  ClassElement get enclosingElement => super.enclosingElement as ClassElement;
+  ElementKind get kind => ElementKind.CONSTRUCTOR;
+  bool isConst() => hasModifier(Modifier.CONST);
+  bool isFactory() => hasModifier(Modifier.FACTORY);
+  /**
+   * Set whether this constructor represents a factory method to the given value.
+   * @param isFactory {@code true} if this constructor represents a factory method
+   */
+  void set factory(bool isFactory) {
+    setModifier(Modifier.FACTORY, isFactory);
+  }
+}
+/**
+ * Instances of the class {@code DynamicElementImpl} represent the synthetic element representing
+ * the declaration of the type {@code dynamic}.
+ */
+class DynamicElementImpl extends ElementImpl {
+  /**
+   * 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}.
+   */
+  DynamicElementImpl() : super.con2(Keyword.DYNAMIC.syntax, -1) {
+    setModifier(Modifier.SYNTHETIC, true);
+  }
+  ElementKind get kind => ElementKind.DYNAMIC;
+  /**
+   * Return the type defined by this element.
+   * @return the type defined by this element
+   */
+  DynamicTypeImpl get type => _type;
+  /**
+   * 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;
+  }
+}
+/**
+ * The abstract class {@code ElementImpl} implements the behavior common to objects that implement
+ * an {@link Element}.
+ */
+abstract class ElementImpl implements Element {
+  /**
+   * The enclosing element of this element, or {@code null} if this element is at the root of the
+   * element structure.
+   */
+  ElementImpl _enclosingElement;
+  /**
+   * The name of this element.
+   */
+  String _name;
+  /**
+   * The offset of the name of this element in the file that contains the declaration of this
+   * element.
+   */
+  int _nameOffset = 0;
+  /**
+   * A bit-encoded form of the modifiers associated with this element.
+   */
+  Set<Modifier> _modifiers;
+  /**
+   * An array containing all of the metadata associated with this element.
+   */
+  List<Annotation> _metadata = AnnotationImpl.EMPTY_ARRAY;
+  /**
+   * 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);
+  }
+  _jtd_constructor_129_impl(Identifier name) {
+    _jtd_constructor_130_impl(name == null ? "" : name.name, name == null ? -1 : name.offset);
+  }
+  /**
+   * Initialize a newly created 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
+   */
+  ElementImpl.con2(String name, int nameOffset) {
+    _jtd_constructor_130_impl(name, nameOffset);
+  }
+  _jtd_constructor_130_impl(String name, int nameOffset) {
+    this._name = name;
+    this._nameOffset = nameOffset;
+    this._modifiers = new Set();
+  }
+  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 the child of this element that is uniquely identified by the given identifier, or{@code null} if there is no such child.
+   * @param identifier the identifier used to select a child
+   * @return the child of this element with the given identifier
+   */
+  ElementImpl getChild(String identifier) => null;
+  AnalysisContext get context {
+    if (_enclosingElement == null) {
+      return null;
+    }
+    return _enclosingElement.context;
+  }
+  Element get enclosingElement => _enclosingElement;
+  LibraryElement get library => getAncestor(LibraryElement);
+  ElementLocation get location => new ElementLocationImpl.con1(this);
+  List<Annotation> get metadata => _metadata;
+  String get name => _name;
+  int get nameOffset => _nameOffset;
+  int get hashCode => location.hashCode;
+  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;
+  }
+  /**
+   * Set whether this element is synthetic to correspond to the given value.
+   * @param isSynthetic {@code true} if the element is synthetic
+   */
+  void set synthetic(bool isSynthetic) {
+    setModifier(Modifier.SYNTHETIC, isSynthetic);
+  }
+  /**
+   * Return an identifier that uniquely identifies this element among the children of this element's
+   * parent.
+   * @return an identifier that uniquely identifies this element relative to its parent
+   */
+  String get identifier => name;
+  /**
+   * Return {@code true} if this element has the given modifier associated with it.
+   * @param modifier the modifier being tested for
+   * @return {@code true} if this element has the given modifier associated with it
+   */
+  bool hasModifier(Modifier modifier) => _modifiers.contains(modifier);
+  /**
+   * Set the enclosing element of this element to the given element.
+   * @param element the enclosing element of this element
+   */
+  void set enclosingElement2(ElementImpl element) {
+    _enclosingElement = element;
+  }
+  /**
+   * Set whether the given modifier is associated with this element to correspond to the given
+   * value.
+   * @param modifier the modifier to be set
+   * @param value {@code true} if the modifier is to be associated with this element
+   */
+  void setModifier(Modifier modifier, bool value) {
+    if (value) {
+      _modifiers.add(modifier);
+    } else {
+      _modifiers.remove(modifier);
+    }
+  }
+}
+/**
+ * Instances of the class {@code ElementLocationImpl} implement an {@link ElementLocation}.
+ */
+class ElementLocationImpl implements ElementLocation {
+  /**
+   * The path to the element whose location is represented by this object.
+   */
+  List<String> _components;
+  /**
+   * The character used to separate components in the encoded form.
+   */
+  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_131_impl(Element element) {
+    List<String> components = new List<String>();
+    Element ancestor = element;
+    while (ancestor != null) {
+      components.insertRange(0, 1, (ancestor as ElementImpl).identifier);
+      ancestor = ancestor.enclosingElement;
+    }
+    this._components = new List.from(components);
+  }
+  /**
+   * Initialize a newly created location from the given encoded form.
+   * @param encoding the encoded form of a location
+   */
+  ElementLocationImpl.con2(String encoding) {
+    _jtd_constructor_132_impl(encoding);
+  }
+  _jtd_constructor_132_impl(String encoding) {
+    this._components = decode(encoding);
+  }
+  bool operator ==(Object object) {
+    if (object is! ElementLocationImpl) {
+      return false;
+    }
+    ElementLocationImpl location = object as ElementLocationImpl;
+    return JavaArrays.equals(_components, location._components);
+  }
+  /**
+   * Return the path to the element whose location is represented by this object.
+   * @return the path to the element whose location is represented by this object
+   */
+  List<String> get components => _components;
+  String get encoding {
+    StringBuffer builder = new StringBuffer();
+    int length2 = _components.length;
+    for (int i = 0; i < length2; i++) {
+      if (i > 0) {
+        builder.addCharCode(ElementLocationImpl._SEPARATOR_CHAR);
+      }
+      encode(builder, _components[i]);
+    }
+    return builder.toString();
+  }
+  int get hashCode => JavaArrays.makeHashCode(_components);
+  /**
+   * Decode the encoded form of a location into an array of components.
+   * @param encoding the encoded form of a location
+   * @return the components that were encoded
+   */
+  List<String> decode(String encoding) {
+    List<String> components = new List<String>();
+    StringBuffer builder = new StringBuffer();
+    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);
+          index += 2;
+        } else {
+          components.add(builder.toString());
+          builder.clear();
+          index++;
+        }
+      } else {
+        builder.addCharCode(currentChar);
+        index++;
+      }
+    }
+    if (builder.length > 0) {
+      components.add(builder.toString());
+    }
+    return new List.from(components);
+  }
+  /**
+   * Append an encoded form of the given component to the given builder.
+   * @param builder the builder to which the encoded component is to be appended
+   * @param component the component to be appended to the builder
+   */
+  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);
+      }
+      builder.addCharCode(currentChar);
+    }
+  }
+}
+/**
+ * The abstract class {@code ExecutableElementImpl} implements the behavior common to{@code ExecutableElement}s.
+ */
+abstract class ExecutableElementImpl extends ElementImpl implements ExecutableElement {
+  /**
+   * An array containing all of the functions defined within this executable element.
+   */
+  List<ExecutableElement> _functions = EMPTY_ARRAY;
+  /**
+   * An array containing all of the labels defined within this executable element.
+   */
+  List<LabelElement> _labels = LabelElementImpl.EMPTY_ARRAY;
+  /**
+   * An array containing all of the local variables defined within this executable element.
+   */
+  List<VariableElement> _localVariables = VariableElementImpl.EMPTY_ARRAY;
+  /**
+   * An array containing all of the parameters defined by this executable element.
+   */
+  List<ParameterElement> _parameters = ParameterElementImpl.EMPTY_ARRAY;
+  /**
+   * The type of function defined by this executable element.
+   */
+  FunctionType _type;
+  /**
+   * An empty array of executable elements.
+   */
+  static List<ExecutableElement> EMPTY_ARRAY = new List<ExecutableElement>.fixedLength(0);
+  /**
+   * Initialize a newly created executable element to have the given name.
+   * @param name the name of this element
+   */
+  ExecutableElementImpl.con1(Identifier name) : super.con1(name) {
+    _jtd_constructor_133_impl(name);
+  }
+  _jtd_constructor_133_impl(Identifier name) {
+  }
+  /**
+   * Initialize a newly created executable 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
+   */
+  ExecutableElementImpl.con2(String name, int nameOffset) : super.con2(name, nameOffset) {
+    _jtd_constructor_134_impl(name, nameOffset);
+  }
+  _jtd_constructor_134_impl(String name, int nameOffset) {
+  }
+  ElementImpl getChild(String identifier) {
+    for (ExecutableElement function in _functions) {
+      if ((function as ExecutableElementImpl).identifier == identifier) {
+        return function as ExecutableElementImpl;
+      }
+    }
+    for (LabelElement label in _labels) {
+      if ((label as LabelElementImpl).identifier == identifier) {
+        return label as LabelElementImpl;
+      }
+    }
+    for (VariableElement variable in _localVariables) {
+      if ((variable as VariableElementImpl).identifier == identifier) {
+        return variable as VariableElementImpl;
+      }
+    }
+    for (ParameterElement parameter in _parameters) {
+      if ((parameter as ParameterElementImpl).identifier == identifier) {
+        return parameter as ParameterElementImpl;
+      }
+    }
+    return null;
+  }
+  List<ExecutableElement> get functions => _functions;
+  List<LabelElement> get labels => _labels;
+  List<VariableElement> get localVariables => _localVariables;
+  List<ParameterElement> get parameters => _parameters;
+  FunctionType get type => _type;
+  /**
+   * 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;
+    }
+    this._functions = functions;
+  }
+  /**
+   * 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;
+    }
+    this._labels = labels;
+  }
+  /**
+   * 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;
+    }
+    this._localVariables = localVariables;
+  }
+  /**
+   * 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;
+    }
+    this._parameters = parameters;
+  }
+  /**
+   * 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;
+  }
+}
+/**
+ * Instances of the class {@code ExportElementImpl} implement an {@link ExportElement}.
+ */
+class ExportElementImpl extends ElementImpl implements ExportElement {
+  /**
+   * The library that is exported from this library by this export directive.
+   */
+  LibraryElement _exportedLibrary;
+  /**
+   * The combinators that were specified as part of the export directive in the order in which they
+   * were specified.
+   */
+  List<NamespaceCombinator> _combinators = NamespaceCombinator.EMPTY_ARRAY;
+  /**
+   * Initialize a newly created export element.
+   */
+  ExportElementImpl() : super.con1(null) {
+  }
+  List<NamespaceCombinator> get combinators => _combinators;
+  LibraryElement get exportedLibrary => _exportedLibrary;
+  ElementKind get kind => ElementKind.EXPORT;
+  /**
+   * Set the combinators that were specified as part of the export directive to the given array of
+   * combinators.
+   * @param combinators the combinators that were specified as part of the export directive
+   */
+  void set combinators2(List<NamespaceCombinator> combinators) {
+    this._combinators = combinators;
+  }
+  /**
+   * 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;
+  }
+}
+/**
+ * Instances of the class {@code FieldElementImpl} implement a {@code FieldElement}.
+ */
+class FieldElementImpl extends VariableElementImpl implements FieldElement {
+  /**
+   * The getter associated with this field.
+   */
+  PropertyAccessorElement _getter;
+  /**
+   * The setter associated with this field, or {@code null} if the field is effectively{@code final} and therefore does not have a setter associated with it.
+   */
+  PropertyAccessorElement _setter;
+  /**
+   * An empty array of field elements.
+   */
+  static List<FieldElement> EMPTY_ARRAY = new List<FieldElement>.fixedLength(0);
+  /**
+   * Initialize a newly created field element to have the given name.
+   * @param name the name of this element
+   */
+  FieldElementImpl.con1(Identifier name) : super.con1(name) {
+    _jtd_constructor_136_impl(name);
+  }
+  _jtd_constructor_136_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_137_impl(String name) {
+    synthetic = true;
+  }
+  PropertyAccessorElement get getter => _getter;
+  ElementKind get kind => ElementKind.FIELD;
+  PropertyAccessorElement get setter => _setter;
+  bool isStatic() => hasModifier(Modifier.STATIC);
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * Set whether this field is static to correspond to the given value.
+   * @param isStatic {@code true} if the field is static
+   */
+  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 {
+  /**
+   * An empty array of function elements.
+   */
+  static List<FunctionElement> EMPTY_ARRAY = new List<FunctionElement>.fixedLength(0);
+  /**
+   * Initialize a newly created synthetic function element.
+   */
+  FunctionElementImpl() : super.con2("", -1) {
+    _jtd_constructor_138_impl();
+  }
+  _jtd_constructor_138_impl() {
+    synthetic = true;
+  }
+  /**
+   * Initialize a newly created function element to have the given name.
+   * @param name the name of this element
+   */
+  FunctionElementImpl.con1(Identifier name) : super.con1(name) {
+    _jtd_constructor_139_impl(name);
+  }
+  _jtd_constructor_139_impl(Identifier name) {
+  }
+  String get identifier => name;
+  ElementKind get kind => ElementKind.FUNCTION;
+}
+/**
+ * Instances of the class {@code ShowCombinatorImpl} implement a {@link ShowCombinator}.
+ */
+class HideCombinatorImpl implements HideCombinator {
+  /**
+   * The names that are not to be made visible in the importing library even if they are defined in
+   * the imported library.
+   */
+  List<String> _hiddenNames = StringUtilities.EMPTY_ARRAY;
+  /**
+   * Initialize a newly created combinator.
+   */
+  HideCombinatorImpl() : super() {
+  }
+  List<String> get hiddenNames => _hiddenNames;
+  /**
+   * Set the names that are not to be made visible in the importing library even if they are defined
+   * 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;
+  }
+}
+/**
+ * Instances of the class {@code HtmlElementImpl} implement an {@link HtmlElement}.
+ */
+class HtmlElementImpl extends ElementImpl implements HtmlElement {
+  /**
+   * An empty array of HTML file elements.
+   */
+  static List<HtmlElement> EMPTY_ARRAY = new List<HtmlElement>.fixedLength(0);
+  /**
+   * The analysis context in which this library is defined.
+   */
+  AnalysisContext _context;
+  /**
+   * The libraries contained in or referenced from script tags in the HTML file.
+   */
+  List<LibraryElement> _libraries = LibraryElementImpl.EMPTY_ARRAY;
+  /**
+   * The source that corresponds to this HTML file.
+   */
+  Source _source;
+  /**
+   * Initialize a newly created HTML element to have the given name.
+   * @param context the analysis context in which the HTML file is defined
+   * @param name the name of this element
+   */
+  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;
+  AnalysisContext get context => _context;
+  ElementKind get kind => ElementKind.HTML;
+  List<LibraryElement> get libraries => _libraries;
+  Source get source => _source;
+  int get hashCode => _source.hashCode;
+  /**
+   * Set the libraries contained in or referenced from script tags in the HTML file to the given
+   * 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;
+  }
+  /**
+   * 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;
+  }
+}
+/**
+ * Instances of the class {@code ImportElementImpl} implement an {@link ImportElement}.
+ */
+class ImportElementImpl extends ElementImpl implements ImportElement {
+  /**
+   * The library that is imported into this library by this import directive.
+   */
+  LibraryElement _importedLibrary;
+  /**
+   * The combinators that were specified as part of the import directive in the order in which they
+   * were specified.
+   */
+  List<NamespaceCombinator> _combinators = NamespaceCombinator.EMPTY_ARRAY;
+  /**
+   * The prefix that was specified as part of the import directive, or {@code null} if there was no
+   * prefix specified.
+   */
+  PrefixElement _prefix;
+  /**
+   * Initialize a newly created import element.
+   */
+  ImportElementImpl() : super.con1(null) {
+  }
+  List<NamespaceCombinator> get combinators => _combinators;
+  LibraryElement get importedLibrary => _importedLibrary;
+  ElementKind get kind => ElementKind.IMPORT;
+  PrefixElement get prefix => _prefix;
+  /**
+   * Set the combinators that were specified as part of the import directive to the given array of
+   * combinators.
+   * @param combinators the combinators that were specified as part of the import directive
+   */
+  void set combinators3(List<NamespaceCombinator> combinators) {
+    this._combinators = combinators;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+}
+/**
+ * Instances of the class {@code LabelElementImpl} implement a {@code LabelElement}.
+ */
+class LabelElementImpl extends ElementImpl implements LabelElement {
+  /**
+   * A flag indicating whether this label is associated with a {@code switch} statement.
+   */
+  bool _onSwitchStatement = false;
+  /**
+   * A flag indicating whether this label is associated with a {@code switch} member ({@code case}or {@code default}).
+   */
+  bool _onSwitchMember = false;
+  /**
+   * An empty array of label elements.
+   */
+  static List<LabelElement> EMPTY_ARRAY = new List<LabelElement>.fixedLength(0);
+  /**
+   * Initialize a newly created label element to have the given name.
+   * @param name the name of this element
+   * @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
+   */
+  LabelElementImpl(Identifier name, bool onSwitchStatement, bool onSwitchMember) : super.con1(name) {
+    this._onSwitchStatement = onSwitchStatement;
+    this._onSwitchMember = onSwitchMember;
+  }
+  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}).
+   * @return {@code true} if this label is associated with a {@code switch} member
+   */
+  bool isOnSwitchMember() => _onSwitchMember;
+  /**
+   * Return {@code true} if this label is associated with a {@code switch} statement.
+   * @return {@code true} if this label is associated with a {@code switch} statement
+   */
+  bool isOnSwitchStatement() => _onSwitchStatement;
+}
+/**
+ * Instances of the class {@code LibraryElementImpl} implement a {@code LibraryElement}.
+ */
+class LibraryElementImpl extends ElementImpl implements LibraryElement {
+  /**
+   * An empty array of library elements.
+   */
+  static List<LibraryElement> EMPTY_ARRAY = new List<LibraryElement>.fixedLength(0);
+  /**
+   * The analysis context in which this library is defined.
+   */
+  AnalysisContext _context;
+  /**
+   * The compilation unit that defines this library.
+   */
+  CompilationUnitElement _definingCompilationUnit;
+  /**
+   * The entry point for this library, or {@code null} if this library does not have an entry point.
+   */
+  FunctionElement _entryPoint;
+  /**
+   * An array containing specifications of all of the imports defined in this library.
+   */
+  List<ImportElement> _imports = ImportElement.EMPTY_ARRAY;
+  /**
+   * An array containing specifications of all of the exports defined in this library.
+   */
+  List<ExportElement> _exports = ExportElement.EMPTY_ARRAY;
+  /**
+   * An array containing all of the compilation units that are included in this library using a{@code part} directive.
+   */
+  List<CompilationUnitElement> _parts = CompilationUnitElementImpl.EMPTY_ARRAY;
+  /**
+   * Initialize a newly created library element to have the given name.
+   * @param context the analysis context in which the library is defined
+   * @param name the name of this element
+   */
+  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;
+    }
+    for (CompilationUnitElement part in _parts) {
+      if ((part as CompilationUnitElementImpl).identifier == identifier) {
+        return part as CompilationUnitElementImpl;
+      }
+    }
+    return null;
+  }
+  AnalysisContext get context => _context;
+  CompilationUnitElement get definingCompilationUnit => _definingCompilationUnit;
+  FunctionElement get entryPoint => _entryPoint;
+  List<ExportElement> get exports => _exports;
+  String get identifier => _definingCompilationUnit.source.fullName;
+  List<LibraryElement> get importedLibraries {
+    Set<LibraryElement> libraries = new Set<LibraryElement>();
+    for (ImportElement element in _imports) {
+      LibraryElement prefix = element.importedLibrary;
+      javaSetAdd(libraries, prefix);
+    }
+    return new List.from(libraries);
+  }
+  List<ImportElement> get imports => _imports;
+  ElementKind get kind => ElementKind.LIBRARY;
+  List<CompilationUnitElement> get parts => _parts;
+  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);
+      }
+    }
+    return new List.from(prefixes);
+  }
+  int get hashCode => _definingCompilationUnit.hashCode;
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+    }
+    this._parts = parts;
+  }
+}
+/**
+ * Instances of the class {@code MethodElementImpl} implement a {@code MethodElement}.
+ */
+class MethodElementImpl extends ExecutableElementImpl implements MethodElement {
+  /**
+   * An empty array of method elements.
+   */
+  static List<MethodElement> EMPTY_ARRAY = new List<MethodElement>.fixedLength(0);
+  /**
+   * Initialize a newly created method element to have the given name.
+   * @param name the name of this element
+   */
+  MethodElementImpl(Identifier name) : super.con1(name) {
+  }
+  ClassElement get enclosingElement => super.enclosingElement as ClassElement;
+  ElementKind get kind => ElementKind.METHOD;
+  bool isAbstract() => hasModifier(Modifier.ABSTRACT);
+  bool isStatic() => hasModifier(Modifier.STATIC);
+  /**
+   * Set whether this method is abstract to correspond to the given value.
+   * @param isAbstract {@code true} if the method is abstract
+   */
+  void set abstract(bool isAbstract) {
+    setModifier(Modifier.ABSTRACT, isAbstract);
+  }
+  /**
+   * Set whether this method is static to correspond to the given value.
+   * @param isStatic {@code true} if the method is static
+   */
+  void set static(bool isStatic) {
+    setModifier(Modifier.STATIC, isStatic);
+  }
+  String toString() {
+    StringBuffer builder = new StringBuffer();
+    builder.add("method ");
+    builder.add(enclosingElement.name);
+    builder.add(".");
+    builder.add(name);
+    builder.add(type);
+    return builder.toString();
+  }
+}
+/**
+ * The enumeration {@code Modifier} defines constants for all of the modifiers defined by the Dart
+ * language.
+ */
+class Modifier {
+  static final Modifier ABSTRACT = new Modifier('ABSTRACT', 0);
+  static final Modifier CONST = new Modifier('CONST', 1);
+  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];
+  final String __name;
+  final int __ordinal;
+  Modifier(this.__name, this.__ordinal) {
+  }
+  String toString() => __name;
+}
+/**
+ * Instances of the class {@code MultiplyDefinedElementImpl} represent a collection of elements that
+ * have the same name within the same scope.
+ */
+class MultiplyDefinedElementImpl implements MultiplyDefinedElement {
+  /**
+   * The analysis context in which the multiply defined elements are defined.
+   */
+  AnalysisContext _context;
+  /**
+   * The name of the conflicting elements.
+   */
+  String _name;
+  /**
+   * A list containing all of the elements that conflict.
+   */
+  List<Element> _conflictingElements;
+  /**
+   * Initialize a newly created element to represent a list of conflicting elements.
+   * @param context the analysis context in which the multiply defined elements are defined
+   * @param firstElement the first element that conflicts
+   * @param secondElement the second element that conflicts
+   */
+  MultiplyDefinedElementImpl(AnalysisContext context, Element firstElement, Element secondElement) {
+    _name = firstElement.name;
+    _conflictingElements = computeConflictingElements(firstElement, secondElement);
+  }
+  Element getAncestor(Type elementClass) => null;
+  List<Element> get conflictingElements => _conflictingElements;
+  AnalysisContext get context => _context;
+  Element get enclosingElement => null;
+  ElementKind get kind => ElementKind.ERROR;
+  LibraryElement get library => null;
+  ElementLocation get location => null;
+  List<Annotation> get metadata => AnnotationImpl.EMPTY_ARRAY;
+  String get name => _name;
+  int get nameOffset => -1;
+  bool isSynthetic() => true;
+  /**
+   * 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.
+   * @param elements the list to which the element(s) are to be added
+   * @param element the element(s) to be added
+   */
+  void add(List<Element> elements, Element element) {
+    if (element is MultiplyDefinedElementImpl) {
+      for (Element conflictingElement in (element as MultiplyDefinedElementImpl)._conflictingElements) {
+        elements.add(conflictingElement);
+      }
+    } else {
+      elements.add(element);
+    }
+  }
+  /**
+   * Use the given elements to construct an array of conflicting elements. If either of the given
+   * elements are multiply-defined elements then the conflicting elements they represent will be
+   * included in the array. Otherwise, the element itself will be included.
+   * @param firstElement the first element to be included
+   * @param secondElement the second element to be included
+   * @return an array containing all of the conflicting elements
+   */
+  List<Element> computeConflictingElements(Element firstElement, Element secondElement) {
+    List<Element> elements = new List<Element>();
+    add(elements, firstElement);
+    add(elements, secondElement);
+    return new List.from(elements);
+  }
+}
+/**
+ * Instances of the class {@code ParameterElementImpl} implement a {@code ParameterElement}.
+ */
+class ParameterElementImpl extends VariableElementImpl implements ParameterElement {
+  /**
+   * The kind of this parameter.
+   */
+  ParameterKind _parameterKind;
+  /**
+   * An empty array of field elements.
+   */
+  static List<ParameterElement> EMPTY_ARRAY = new List<ParameterElement>.fixedLength(0);
+  /**
+   * Initialize a newly created parameter element to have the given name.
+   * @param name the name of this element
+   */
+  ParameterElementImpl(Identifier name) : super.con1(name) {
+  }
+  ElementKind get kind => ElementKind.PARAMETER;
+  ParameterKind get parameterKind => _parameterKind;
+  /**
+   * 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;
+  }
+  String toString() => "parameter ${type} ${name} (${kind})";
+}
+/**
+ * Instances of the class {@code PrefixElementImpl} implement a {@code PrefixElement}.
+ */
+class PrefixElementImpl extends ElementImpl implements PrefixElement {
+  /**
+   * An array containing all of the libraries that are imported using this prefix.
+   */
+  List<LibraryElement> _importedLibraries = LibraryElementImpl.EMPTY_ARRAY;
+  /**
+   * An empty array of prefix elements.
+   */
+  static List<PrefixElement> EMPTY_ARRAY = new List<PrefixElement>.fixedLength(0);
+  /**
+   * Initialize a newly created prefix element to have the given name.
+   * @param name the name of this element
+   */
+  PrefixElementImpl(Identifier name) : super.con1(name) {
+  }
+  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;
+    }
+    this._importedLibraries = importedLibraries;
+  }
+}
+/**
+ * Instances of the class {@code PropertyAccessorElementImpl} implement a{@code PropertyAccessorElement}.
+ */
+class PropertyAccessorElementImpl extends ExecutableElementImpl implements PropertyAccessorElement {
+  /**
+   * The field associated with this accessor.
+   */
+  FieldElement _field;
+  /**
+   * An empty array of property accessor elements.
+   */
+  static List<PropertyAccessorElement> EMPTY_ARRAY = new List<PropertyAccessorElement>.fixedLength(0);
+  /**
+   * Initialize a newly created synthetic property accessor element to be associated with the given
+   * field.
+   * @param name the name of this element
+   */
+  PropertyAccessorElementImpl.con1(FieldElementImpl field) : super.con2(field.name, -1) {
+    _jtd_constructor_150_impl(field);
+  }
+  _jtd_constructor_150_impl(FieldElementImpl field) {
+    this._field = field;
+    synthetic = true;
+  }
+  /**
+   * Initialize a newly created property accessor element to have the given name.
+   * @param name the name of this element
+   */
+  PropertyAccessorElementImpl.con2(Identifier name) : super.con1(name) {
+    _jtd_constructor_151_impl(name);
+  }
+  _jtd_constructor_151_impl(Identifier name) {
+  }
+  FieldElement get field => _field;
+  ElementKind get kind {
+    if (isGetter()) {
+      return ElementKind.GETTER;
+    }
+    return ElementKind.SETTER;
+  }
+  bool isGetter() => hasModifier(Modifier.GETTER);
+  bool isSetter() => hasModifier(Modifier.SETTER);
+  /**
+   * 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;
+  }
+  /**
+   * Set whether this accessor is a getter to correspond to the given value.
+   * @param isGetter {@code true} if the accessor is a getter
+   */
+  void set getter(bool isGetter) {
+    setModifier(Modifier.GETTER, isGetter);
+  }
+  /**
+   * Set whether this accessor is a setter to correspond to the given value.
+   * @param isSetter {@code true} if the accessor is a setter
+   */
+  void set setter(bool isSetter) {
+    setModifier(Modifier.SETTER, isSetter);
+  }
+}
+/**
+ * Instances of the class {@code ShowCombinatorImpl} implement a {@link ShowCombinator}.
+ */
+class ShowCombinatorImpl implements ShowCombinator {
+  /**
+   * The names that are to be made visible in the importing library if they are defined in the
+   * imported library.
+   */
+  List<String> _shownNames = StringUtilities.EMPTY_ARRAY;
+  /**
+   * Initialize a newly created combinator.
+   */
+  ShowCombinatorImpl() : super() {
+  }
+  List<String> get shownNames => _shownNames;
+  /**
+   * Set the names that are to be made visible in the importing library if they are defined in the
+   * 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;
+  }
+}
+/**
+ * Instances of the class {@code TypeAliasElementImpl} implement a {@code TypeAliasElement}.
+ */
+class TypeAliasElementImpl extends ElementImpl implements TypeAliasElement {
+  /**
+   * An array containing all of the parameters defined by this type alias.
+   */
+  List<ParameterElement> _parameters = ParameterElementImpl.EMPTY_ARRAY;
+  /**
+   * The type of function defined by this type alias.
+   */
+  FunctionType _type;
+  /**
+   * An array containing all of the type variables defined for this type.
+   */
+  List<TypeVariableElement> _typeVariables = TypeVariableElementImpl.EMPTY_ARRAY;
+  /**
+   * An empty array of type alias elements.
+   */
+  static List<TypeAliasElement> EMPTY_ARRAY = new List<TypeAliasElement>.fixedLength(0);
+  /**
+   * Initialize a newly created type alias element to have the given name.
+   * @param name the name of this element
+   */
+  TypeAliasElementImpl(Identifier name) : super.con1(name) {
+  }
+  ElementImpl getChild(String identifier) {
+    for (VariableElement parameter in _parameters) {
+      if ((parameter as VariableElementImpl).identifier == identifier) {
+        return parameter as VariableElementImpl;
+      }
+    }
+    for (TypeVariableElement typeVariable in _typeVariables) {
+      if ((typeVariable as TypeVariableElementImpl).identifier == identifier) {
+        return typeVariable as TypeVariableElementImpl;
+      }
+    }
+    return null;
+  }
+  CompilationUnitElement get enclosingElement => super.enclosingElement as CompilationUnitElement;
+  ElementKind get kind => ElementKind.TYPE_ALIAS;
+  List<ParameterElement> get parameters => _parameters;
+  FunctionType get type => _type;
+  List<TypeVariableElement> get typeVariables => _typeVariables;
+  /**
+   * 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;
+      }
+    }
+    this._parameters = parameters;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+    }
+    this._typeVariables = typeVariables;
+  }
+}
+/**
+ * Instances of the class {@code TypeVariableElementImpl} implement a {@code TypeVariableElement}.
+ */
+class TypeVariableElementImpl extends ElementImpl implements TypeVariableElement {
+  /**
+   * The type defined by this type variable.
+   */
+  TypeVariableType _type;
+  /**
+   * The type representing the bound associated with this variable, or {@code null} if this variable
+   * does not have an explicit bound.
+   */
+  Type2 _bound;
+  /**
+   * An empty array of type variable elements.
+   */
+  static List<TypeVariableElement> EMPTY_ARRAY = new List<TypeVariableElement>.fixedLength(0);
+  /**
+   * Initialize a newly created type variable element to have the given name.
+   * @param name the name of this element
+   */
+  TypeVariableElementImpl(Identifier name) : super.con1(name) {
+  }
+  Type2 get bound => _bound;
+  ElementKind get kind => ElementKind.TYPE_VARIABLE;
+  TypeVariableType get type => _type;
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+}
+/**
+ * Instances of the class {@code VariableElementImpl} implement a {@code VariableElement}.
+ */
+class VariableElementImpl extends ElementImpl implements VariableElement {
+  /**
+   * The declared type of this variable.
+   */
+  Type2 _type;
+  /**
+   * A synthetic function representing this variable's initializer, or {@code null} if this variable
+   * does not have an initializer.
+   */
+  FunctionElement _initializer;
+  /**
+   * An empty array of variable elements.
+   */
+  static List<VariableElement> EMPTY_ARRAY = new List<VariableElement>.fixedLength(0);
+  /**
+   * Initialize a newly created variable element to have the given name.
+   * @param name the name of this element
+   */
+  VariableElementImpl.con1(Identifier name) : super.con1(name) {
+    _jtd_constructor_155_impl(name);
+  }
+  _jtd_constructor_155_impl(Identifier name) {
+  }
+  /**
+   * Initialize a newly created variable 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
+   */
+  VariableElementImpl.con2(String name, int nameOffset) : super.con2(name, nameOffset) {
+    _jtd_constructor_156_impl(name, nameOffset);
+  }
+  _jtd_constructor_156_impl(String name, int nameOffset) {
+  }
+  FunctionElement get initializer => _initializer;
+  ElementKind get kind => ElementKind.VARIABLE;
+  Type2 get type => _type;
+  bool isConst() => hasModifier(Modifier.CONST);
+  bool isFinal() => hasModifier(Modifier.FINAL);
+  /**
+   * Set whether this variable is const to correspond to the given value.
+   * @param isConst {@code true} if the variable is const
+   */
+  void set const2(bool isConst) {
+    setModifier(Modifier.CONST, isConst);
+  }
+  /**
+   * Set whether this variable is final to correspond to the given value.
+   * @param isFinal {@code true} if the variable is final
+   */
+  void set final2(bool isFinal) {
+    setModifier(Modifier.FINAL, isFinal);
+  }
+  /**
+   * 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;
+    }
+    this._initializer = initializer;
+  }
+  /**
+   * 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;
+  }
+  String toString() => "variable ${type} ${name}";
+}
+/**
+ * The unique instance of the class {@code BottomTypeImpl} implements the type {@code bottom}.
+ */
+class BottomTypeImpl extends TypeImpl {
+  /**
+   * The unique instance of this class.
+   */
+  static BottomTypeImpl _INSTANCE = new BottomTypeImpl();
+  /**
+   * Return the unique instance of this class.
+   * @return the unique instance of this class
+   */
+  static BottomTypeImpl get instance => _INSTANCE;
+  /**
+   * Prevent the creation of instances of this class.
+   */
+  BottomTypeImpl() : super(null, "<bottom>") {
+  }
+  bool operator ==(Object object) => object == this;
+  bool isMoreSpecificThan(Type2 type) => true;
+  bool isSubtypeOf(Type2 type) => true;
+  bool isSupertypeOf(Type2 type) => false;
+  BottomTypeImpl substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) => this;
+}
+/**
+ * The unique instance of the class {@code DynamicTypeImpl} implements the type {@code dynamic}.
+ */
+class DynamicTypeImpl extends TypeImpl {
+  /**
+   * The unique instance of this class.
+   */
+  static DynamicTypeImpl _INSTANCE = new DynamicTypeImpl();
+  /**
+   * Return the unique instance of this class.
+   * @return the unique instance of this class
+   */
+  static DynamicTypeImpl get instance => _INSTANCE;
+  /**
+   * Prevent the creation of instances of this class.
+   */
+  DynamicTypeImpl() : super(new DynamicElementImpl(), Keyword.DYNAMIC.syntax) {
+    (element as DynamicElementImpl).type10 = this;
+  }
+  bool operator ==(Object object) => object is DynamicTypeImpl;
+  bool isMoreSpecificThan(Type2 type) => false;
+  bool isSubtypeOf(Type2 type) => false;
+  bool isSupertypeOf(Type2 type) => true;
+  DynamicTypeImpl substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) => this;
+}
+/**
+ * Instances of the class {@code FunctionTypeImpl} defines the behavior common to objects
+ * representing the type of a function, method, constructor, getter, or setter.
+ */
+class FunctionTypeImpl extends TypeImpl implements FunctionType {
+  /**
+   * Return {@code true} if all of the types in the first array are equal to the corresponding types
+   * in the second array.
+   * @param firstTypes the first array of types being compared
+   * @param secondTypes the second array of types being compared
+   * @return {@code true} if all of the types in the first array are equal to the corresponding
+   * types in the second array
+   */
+  static bool equals2(LinkedHashMap<String, Type2> firstTypes, LinkedHashMap<String, Type2> secondTypes) {
+    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);
+    while (firstIterator.hasNext) {
+      MapEntry<String, Type2> firstEntry = firstIterator.next();
+      MapEntry<String, Type2> secondEntry = secondIterator.next();
+      if (firstEntry.getKey() != secondEntry.getKey() || firstEntry.getValue() != secondEntry.getValue()) {
+        return false;
+      }
+    }
+    return true;
+  }
+  /**
+   * Return a map containing the results of using the given argument types and parameter types to
+   * perform a substitution on all of the values in the given map. The order of the entries will be
+   * preserved.
+   * @param types the types on which a substitution is to be performed
+   * @param argumentTypes the argument types for the substitution
+   * @param parameterTypes the parameter types for the substitution
+   * @return the result of performing the substitution on each of the types
+   */
+  static LinkedHashMap<String, Type2> substitute3(LinkedHashMap<String, Type2> types, List<Type2> argumentTypes, List<Type2> parameterTypes) {
+    LinkedHashMap<String, Type2> newTypes = new LinkedHashMap<String, Type2>();
+    for (MapEntry<String, Type2> entry in getMapEntrySet(types)) {
+      newTypes[entry.getKey()] = entry.getValue().substitute2(argumentTypes, parameterTypes);
+    }
+    return newTypes;
+  }
+  /**
+   * An array containing the actual types of the type arguments.
+   */
+  List<Type2> _typeArguments = TypeImpl.EMPTY_ARRAY;
+  /**
+   * An array containing the types of the normal parameters of this type of function. The parameter
+   * types are in the same order as they appear in the declaration of the function.
+   * @return the types of the normal parameters of this type of function
+   */
+  List<Type2> _normalParameterTypes = TypeImpl.EMPTY_ARRAY;
+  /**
+   * A table mapping the names of optional (positional) parameters to the types of the optional
+   * parameters of this type of function.
+   */
+  List<Type2> _optionalParameterTypes = TypeImpl.EMPTY_ARRAY;
+  /**
+   * A table mapping the names of named parameters to the types of the named parameters of this type
+   * of function.
+   */
+  LinkedHashMap<String, Type2> _namedParameterTypes = new LinkedHashMap<String, Type2>();
+  /**
+   * The type of object returned by this type of function.
+   */
+  Type2 _returnType = VoidTypeImpl.instance;
+  /**
+   * Initialize a newly created function type to be declared by the given element and to have the
+   * given name.
+   * @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_200_impl(ExecutableElement element) {
+  }
+  /**
+   * Initialize a newly created function type to be declared by the given element and to have the
+   * given name.
+   * @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_201_impl(TypeAliasElement element) {
+  }
+  bool operator ==(Object object) {
+    if (object is! FunctionTypeImpl) {
+      return false;
+    }
+    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;
+  List<Type2> get normalParameterTypes => _normalParameterTypes;
+  List<Type2> get optionalParameterTypes => _optionalParameterTypes;
+  Type2 get returnType => _returnType;
+  List<Type2> get typeArguments => _typeArguments;
+  int get hashCode {
+    Element element29 = element;
+    if (element29 == null) {
+      return 0;
+    }
+    return element29.hashCode;
+  }
+  bool isSubtypeOf(Type2 type) {
+    if (type == null || type is! FunctionType) {
+      return false;
+    } else if (this == type || this == type) {
+      return true;
+    }
+    FunctionType t = this;
+    FunctionType s = type as FunctionType;
+    if (t.normalParameterTypes.length != s.normalParameterTypes.length) {
+      return false;
+    } else if (t.normalParameterTypes.length > 0) {
+      List<Type2> tTypes = t.normalParameterTypes;
+      List<Type2> sTypes = s.normalParameterTypes;
+      for (int i = 0; i < tTypes.length; i++) {
+        if (!tTypes[i].isAssignableTo(sTypes[i])) {
+          return false;
+        }
+      }
+    }
+    if (t.optionalParameterTypes.length > 0) {
+      List<Type2> tOpTypes = t.optionalParameterTypes;
+      List<Type2> sOpTypes = s.optionalParameterTypes;
+      if (tOpTypes.length < sOpTypes.length) {
+        return false;
+      }
+      for (int i = 0; i < sOpTypes.length; i++) {
+        if (!tOpTypes[i].isAssignableTo(sOpTypes[i])) {
+          return false;
+        }
+      }
+      if (t.namedParameterTypes.length > 0 || s.namedParameterTypes.length > 0) {
+        return false;
+      }
+    } else if (s.optionalParameterTypes.length > 0) {
+      return false;
+    }
+    if (t.namedParameterTypes.length > 0) {
+      Map<String, Type2> namedTypesT = t.namedParameterTypes;
+      Map<String, Type2> namedTypesS = s.namedParameterTypes;
+      if (namedTypesT.length < namedTypesS.length) {
+        return false;
+      }
+      HasNextIterator<MapEntry<String, Type2>> iteratorS = new HasNextIterator(getMapEntrySet(namedTypesS).iterator);
+      while (iteratorS.hasNext) {
+        MapEntry<String, Type2> entryS = iteratorS.next();
+        Type2 typeT = namedTypesT[entryS.getKey()];
+        if (typeT == null) {
+          return false;
+        }
+        if (!entryS.getValue().isAssignableTo(typeT)) {
+          return false;
+        }
+      }
+    } else if (s.namedParameterTypes.length > 0) {
+      return false;
+    }
+    return s.returnType == VoidTypeImpl.instance || t.returnType.isAssignableTo(s.returnType);
+  }
+  /**
+   * Set the mapping of the names of named parameters to the types of the named parameters of this
+   * type of function to the given mapping.
+   * @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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  FunctionTypeImpl substitute4(List<Type2> argumentTypes) => substitute2(argumentTypes, typeArguments);
+  FunctionTypeImpl substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) {
+    if (argumentTypes.length != parameterTypes.length) {
+      throw new IllegalArgumentException("argumentTypes.length (${argumentTypes.length}) != parameterTypes.length (${parameterTypes.length})");
+    }
+    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);
+    return newType;
+  }
+  String toString() {
+    StringBuffer builder = new StringBuffer();
+    builder.add("(");
+    bool needsComma = false;
+    if (_normalParameterTypes.length > 0) {
+      for (Type2 type in _normalParameterTypes) {
+        if (needsComma) {
+          builder.add(", ");
+        } else {
+          needsComma = true;
+        }
+        builder.add(type);
+      }
+    }
+    if (_optionalParameterTypes.length > 0) {
+      if (needsComma) {
+        builder.add(", ");
+        needsComma = false;
+      }
+      builder.add("[");
+      for (Type2 type in _optionalParameterTypes) {
+        if (needsComma) {
+          builder.add(", ");
+        } else {
+          needsComma = true;
+        }
+        builder.add(type);
+      }
+      builder.add("]");
+      needsComma = true;
+    }
+    if (_namedParameterTypes.length > 0) {
+      if (needsComma) {
+        builder.add(", ");
+        needsComma = false;
+      }
+      builder.add("{");
+      for (MapEntry<String, Type2> entry in getMapEntrySet(_namedParameterTypes)) {
+        if (needsComma) {
+          builder.add(", ");
+        } else {
+          needsComma = true;
+        }
+        builder.add(entry.getKey());
+        builder.add(": ");
+        builder.add(entry.getValue());
+      }
+      builder.add("}");
+      needsComma = true;
+    }
+    builder.add(") -> ");
+    builder.add(_returnType);
+    return builder.toString();
+  }
+}
+/**
+ * Instances of the class {@code InterfaceTypeImpl} defines the behavior common to objects
+ * representing the type introduced by either a class or an interface, or a reference to such a
+ * type.
+ */
+class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
+  /**
+   * An empty array of types.
+   */
+  static List<InterfaceType> EMPTY_ARRAY = new List<InterfaceType>.fixedLength(0);
+  /**
+   * This method computes the longest inheritance path from some passed {@link Type} to Object.
+   * @param type the {@link Type} to compute the longest inheritance path of from the passed{@link Type} to Object
+   * @return the computed longest inheritance path to Object
+   * @see #computeLongestInheritancePathToObject(Type,int)
+   * @see InterfaceType#getLeastUpperBound(Type)
+   */
+  static int computeLongestInheritancePathToObject(InterfaceType type) => computeLongestInheritancePathToObject2(type, 0);
+  /**
+   * Returns the set of all superinterfaces of the passed {@link Type}.
+   * @param type the {@link Type} to compute the set of superinterfaces of
+   * @return the {@link Set} of superinterfaces of the passed {@link Type}
+   * @see #computeSuperinterfaceSet(Type,HashSet)
+   * @see #getLeastUpperBound(Type)
+   */
+  static Set<InterfaceType> computeSuperinterfaceSet(InterfaceType type) => computeSuperinterfaceSet2(type, new Set<InterfaceType>());
+  /**
+   * This method computes the longest inheritance path from some passed {@link Type} to Object. This
+   * method calls itself recursively, callers should use the public method{@link #computeLongestInheritancePathToObject(Type)}.
+   * @param type the {@link Type} to compute the longest inheritance path of from the passed{@link Type} to Object
+   * @param depth a field used recursively
+   * @return the computed longest inheritance path to Object
+   * @see #computeLongestInheritancePathToObject(Type)
+   * @see #getLeastUpperBound(Type)
+   */
+  static int computeLongestInheritancePathToObject2(InterfaceType type, int depth) {
+    ClassElement classElement = type.element;
+    if (classElement.supertype == null) {
+      return depth;
+    }
+    List<InterfaceType> superinterfaces = classElement.interfaces;
+    int longestPath = 1;
+    int pathLength;
+    if (superinterfaces.length > 0) {
+      for (InterfaceType superinterface in superinterfaces) {
+        pathLength = computeLongestInheritancePathToObject2(superinterface, depth + 1);
+        if (pathLength > longestPath) {
+          longestPath = pathLength;
+        }
+      }
+    }
+    InterfaceType supertype3 = classElement.supertype;
+    pathLength = computeLongestInheritancePathToObject2(supertype3, depth + 1);
+    if (pathLength > longestPath) {
+      longestPath = pathLength;
+    }
+    return longestPath;
+  }
+  /**
+   * Returns the set of all superinterfaces of the passed {@link Type}. This is a recursive method,
+   * callers should call the public {@link #computeSuperinterfaceSet(Type)}.
+   * @param type the {@link Type} to compute the set of superinterfaces of
+   * @param set a {@link HashSet} used recursively by this method
+   * @return the {@link Set} of superinterfaces of the passed {@link Type}
+   * @see #computeSuperinterfaceSet(Type)
+   * @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;
+      List<InterfaceType> superinterfaces = classElement.interfaces;
+      for (InterfaceType superinterface in superinterfaces) {
+        javaSetAdd(set, superinterface);
+        computeSuperinterfaceSet2(superinterface, set);
+      }
+      InterfaceType supertype4 = classElement.supertype;
+      if (supertype4 != null) {
+        javaSetAdd(set, supertype4);
+        computeSuperinterfaceSet2(supertype4, set);
+      }
+    }
+    return set;
+  }
+  /**
+   * An array containing the actual types of the type arguments.
+   */
+  List<Type2> _typeArguments = TypeImpl.EMPTY_ARRAY;
+  /**
+   * Initialize a newly created type to be declared by the given element.
+   * @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_202_impl(ClassElement element) {
+  }
+  /**
+   * Initialize a newly created type to have the given name. This constructor should only be used in
+   * cases where there is no declaration of the type.
+   * @param name the name of the type
+   */
+  InterfaceTypeImpl.con2(String name) : super(null, name) {
+    _jtd_constructor_203_impl(name);
+  }
+  _jtd_constructor_203_impl(String name) {
+  }
+  bool operator ==(Object object) {
+    if (object is! InterfaceTypeImpl) {
+      return false;
+    }
+    InterfaceTypeImpl otherType = object as InterfaceTypeImpl;
+    return element == otherType.element && JavaArrays.equals(_typeArguments, otherType._typeArguments);
+  }
+  ClassElement get element => super.element as ClassElement;
+  Type2 getLeastUpperBound(Type2 type) {
+    Type2 dynamicType = DynamicTypeImpl.instance;
+    if (this == dynamicType || type == dynamicType) {
+      return dynamicType;
+    }
+    if (type == null || type is! InterfaceType) {
+      return null;
+    }
+    InterfaceType i = this;
+    InterfaceType j = type as InterfaceType;
+    Set<InterfaceType> si = computeSuperinterfaceSet(i);
+    Set<InterfaceType> sj = computeSuperinterfaceSet(j);
+    javaSetAdd(si, i);
+    javaSetAdd(sj, j);
+    si.retainAll(sj);
+    Set<InterfaceType> s = si;
+    List<InterfaceType> sn = new List.from(s);
+    List<int> depths = new List<int>.fixedLength(sn.length);
+    int maxDepth = 0;
+    for (int n = 0; n < sn.length; n++) {
+      depths[n] = computeLongestInheritancePathToObject(sn[n]);
+      if (depths[n] > maxDepth) {
+        maxDepth = depths[n];
+      }
+    }
+    for (; maxDepth >= 0; maxDepth--) {
+      int indexOfLeastUpperBound = -1;
+      int numberOfTypesAtMaxDepth = 0;
+      for (int m = 0; m < depths.length; m++) {
+        if (depths[m] == maxDepth) {
+          numberOfTypesAtMaxDepth++;
+          indexOfLeastUpperBound = m;
+        }
+      }
+      if (numberOfTypesAtMaxDepth == 1) {
+        return sn[indexOfLeastUpperBound];
+      }
+    }
+    return null;
+  }
+  Type2 get superclass {
+    ClassElement classElement = element;
+    return element.supertype.substitute2(_typeArguments, TypeVariableTypeImpl.getTypes(classElement.typeVariables));
+  }
+  List<Type2> get typeArguments => _typeArguments;
+  int get hashCode {
+    ClassElement element32 = element;
+    if (element32 == null) {
+      return 0;
+    }
+    return element32.hashCode;
+  }
+  bool isDirectSupertypeOf(InterfaceType type) {
+    ClassElement i = element;
+    ClassElement j = type.element;
+    Type2 supertype5 = j.supertype;
+    if (supertype5 == null) {
+      return false;
+    }
+    ClassElement supertypeElement = supertype5.element as ClassElement;
+    if (supertypeElement == i) {
+      return true;
+    }
+    for (Type2 interfaceType in j.interfaces) {
+      if (interfaceType == i) {
+        return true;
+      }
+    }
+    for (Type2 mixinType in j.mixins) {
+      if (mixinType == i) {
+        return true;
+      }
+    }
+    return false;
+  }
+  bool isMoreSpecificThan(Type2 type) {
+    if (type == DynamicTypeImpl.instance) {
+      return true;
+    } else if (type is! InterfaceType) {
+      return false;
+    }
+    InterfaceType s = type as InterfaceType;
+    if (this == s) {
+      return true;
+    }
+    if (s.isDirectSupertypeOf(this)) {
+      return true;
+    }
+    ClassElement tElement = element;
+    ClassElement sElement = s.element;
+    if (tElement == sElement) {
+      List<Type2> tArguments = typeArguments;
+      List<Type2> sArguments = s.typeArguments;
+      if (tArguments.length != sArguments.length) {
+        return false;
+      }
+      for (int i = 0; i < tArguments.length; i++) {
+        if (!tArguments[i].isMoreSpecificThan(sArguments[i])) {
+          return false;
+        }
+      }
+      return true;
+    }
+    if (element.supertype == null) {
+      return false;
+    }
+    return element.supertype.isMoreSpecificThan(type);
+  }
+  bool isSubtypeOf(Type2 type) {
+    if (type == DynamicTypeImpl.instance) {
+      return true;
+    } else if (type is TypeVariableType) {
+      return true;
+    } else if (type is! InterfaceType) {
+      return false;
+    } else if (this == type) {
+      return true;
+    }
+    InterfaceType typeT = this;
+    InterfaceType typeS = type as InterfaceType;
+    ClassElement elementT = element;
+    if (elementT == null) {
+      return false;
+    }
+    typeT = substitute2(_typeArguments, TypeVariableTypeImpl.getTypes(elementT.typeVariables));
+    if (typeT == typeS) {
+      return true;
+    } else if (elementT == typeS.element) {
+      List<Type2> typeTArgs = typeT.typeArguments;
+      List<Type2> typeSArgs = typeS.typeArguments;
+      if (typeTArgs.length != typeSArgs.length) {
+        return false;
+      }
+      for (int i = 0; i < typeTArgs.length; i++) {
+        if (!typeTArgs[i].isSubtypeOf(typeSArgs[i])) {
+          return false;
+        }
+      }
+      return true;
+    }
+    Type2 supertype6 = elementT.supertype;
+    if (supertype6 == null) {
+      return false;
+    }
+    List<Type2> interfaceTypes = elementT.interfaces;
+    for (Type2 interfaceType in interfaceTypes) {
+      if (interfaceType.isSubtypeOf(typeS)) {
+        return true;
+      }
+    }
+    List<Type2> mixinTypes = elementT.mixins;
+    for (Type2 mixinType in mixinTypes) {
+      if (mixinType == typeS) {
+        return true;
+      }
+    }
+    return supertype6.isSubtypeOf(typeS);
+  }
+  /**
+   * 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;
+  }
+  InterfaceTypeImpl substitute5(List<Type2> argumentTypes) => substitute2(argumentTypes, typeArguments);
+  InterfaceTypeImpl substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) {
+    if (argumentTypes.length != parameterTypes.length) {
+      throw new IllegalArgumentException("argumentTypes.length (${argumentTypes.length}) != parameterTypes.length (${parameterTypes.length})");
+    }
+    if (argumentTypes.length == 0) {
+      return this;
+    }
+    InterfaceTypeImpl newType = new InterfaceTypeImpl.con1(element);
+    newType.typeArguments5 = TypeImpl.substitute(_typeArguments, argumentTypes, parameterTypes);
+    return newType;
+  }
+}
+/**
+ * The abstract class {@code TypeImpl} implements the behavior common to objects representing the
+ * declared type of elements in the element model.
+ */
+abstract class TypeImpl implements Type2 {
+  /**
+   * Return an array containing the results of using the given argument types and parameter types to
+   * perform a substitution on all of the given types.
+   * @param types the types on which a substitution is to be performed
+   * @param argumentTypes the argument types for the substitution
+   * @param parameterTypes the parameter types for the substitution
+   * @return the result of performing the substitution on each of the types
+   */
+  static List<Type2> substitute(List<Type2> types, List<Type2> argumentTypes, List<Type2> parameterTypes) {
+    int length6 = types.length;
+    List<Type2> newTypes = new List<Type2>.fixedLength(length6);
+    for (int i = 0; i < length6; i++) {
+      newTypes[i] = types[i].substitute2(argumentTypes, parameterTypes);
+    }
+    return newTypes;
+  }
+  /**
+   * The element representing the declaration of this type, or {@code null} if the type has not, or
+   * cannot, be associated with an element.
+   */
+  Element _element;
+  /**
+   * The name of this type, or {@code null} if the type does not have a name.
+   */
+  String _name;
+  /**
+   * An empty array of types.
+   */
+  static List<Type2> EMPTY_ARRAY = new List<Type2>.fixedLength(0);
+  /**
+   * Initialize a newly created type to be declared by the given element and to have the given name.
+   * @param element the element representing the declaration of the type
+   * @param name the name of the type
+   */
+  TypeImpl(Element element, String name) {
+    this._element = element;
+    this._name = name;
+  }
+  Element get element => _element;
+  Type2 getLeastUpperBound(Type2 type) => null;
+  String get name => _name;
+  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}";
+}
+/**
+ * Instances of the class {@code TypeVariableTypeImpl} defines the behavior of objects representing
+ * the type introduced by a type variable.
+ */
+class TypeVariableTypeImpl extends TypeImpl implements TypeVariableType {
+  /**
+   * Return an array containing the type variable types defined by the given array of type variable
+   * elements.
+   * @param typeVariables the type variable elements defining the type variable types to be returned
+   * @return the type variable types defined by the type variable elements
+   */
+  static List<TypeVariableType> getTypes(List<TypeVariableElement> typeVariables) {
+    int count = typeVariables.length;
+    List<TypeVariableType> types = new List<TypeVariableType>.fixedLength(count);
+    for (int i = 0; i < count; i++) {
+      types[i] = typeVariables[i].type;
+    }
+    return types;
+  }
+  /**
+   * Initialize a newly created type variable to be declared by the given element and to have the
+   * given name.
+   * @param element the element representing the declaration of the type variable
+   */
+  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;
+  int get hashCode => element.hashCode;
+  bool isMoreSpecificThan(Type2 type) {
+    Type2 upperBound = element.bound;
+    return type == upperBound;
+  }
+  bool isSubtypeOf(Type2 type) => true;
+  Type2 substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) {
+    int length7 = parameterTypes.length;
+    for (int i = 0; i < length7; i++) {
+      if (parameterTypes[i] == this) {
+        return argumentTypes[i];
+      }
+    }
+    return this;
+  }
+}
+/**
+ * The unique instance of the class {@code VoidTypeImpl} implements the type {@code void}.
+ */
+class VoidTypeImpl extends TypeImpl implements VoidType {
+  /**
+   * The unique instance of this class.
+   */
+  static VoidTypeImpl _INSTANCE = new VoidTypeImpl();
+  /**
+   * Return the unique instance of this class.
+   * @return the unique instance of this class
+   */
+  static VoidTypeImpl get instance => _INSTANCE;
+  /**
+   * Prevent the creation of instances of this class.
+   */
+  VoidTypeImpl() : super(null, Keyword.VOID.syntax) {
+  }
+  bool operator ==(Object object) => object == this;
+  bool isSubtypeOf(Type2 type) => type == this || type == DynamicTypeImpl.instance;
+  VoidTypeImpl substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) => this;
+}
+/**
+ * The interface {@code FunctionType} defines the behavior common to objects representing the type
+ * of a function, method, constructor, getter, or setter. Function types come in three variations:
+ * <ol>
+ * <li>The types of functions that only have required parameters. These have the general form
+ * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T</i>.</li>
+ * <li>The types of functions with optional positional parameters. These have the general form
+ * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, [T<sub>n+1</sub>, &hellip;, T<sub>n+k</sub>]) &rarr;
+ * T</i>.</li>
+ * <li>The types of functions with named positional parameters. These have the general form
+ * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {T<sub>x1</sub> x1, &hellip;, T<sub>xk</sub> xk})
+ * &rarr; T</i>.</li>
+ * </ol>
+ */
+abstract class FunctionType implements Type2 {
+  /**
+   * Return a map from the names of named parameters to the types of the named parameters of this
+   * type of function. The entries in the map will be iterated in the same order as the order in
+   * which the named parameters were defined. If there were no named parameters declared then the
+   * map will be empty.
+   * @return a map from the name to the types of the named parameters of this type of function
+   */
+  Map<String, Type2> get namedParameterTypes;
+  /**
+   * Return an array containing the types of the normal parameters of this type of function. The
+   * parameter types are in the same order as they appear in the declaration of the function.
+   * @return the types of the normal parameters of this type of function
+   */
+  List<Type2> get normalParameterTypes;
+  /**
+   * Return a map from the names of optional (positional) parameters to the types of the optional
+   * parameters of this type of function. The entries in the map will be iterated in the same order
+   * as the order in which the optional parameters were defined. If there were no optional
+   * parameters declared then the map will be empty.
+   * @return a map from the name to the types of the optional parameters of this type of function
+   */
+  List<Type2> get optionalParameterTypes;
+  /**
+   * Return the type of object returned by this type of function.
+   * @return the type of object returned by this type of function
+   */
+  Type2 get returnType;
+  /**
+   * Return an array containing the actual types of the type arguments. If this type's element does
+   * not have type parameters, then the array should be empty (although it is possible for type
+   * arguments to be erroneously declared). If the element has type parameters and the actual type
+   * does not explicitly include argument values, then the type "dynamic" will be automatically
+   * provided.
+   * @return the actual types of the type arguments
+   */
+  List<Type2> get typeArguments;
+  /**
+   * Return {@code true} if this type is a subtype of the given type.
+   * <p>
+   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T</i> is a subtype of the
+   * function type <i>(S<sub>1</sub>, &hellip;, S<sub>n</sub>) &rarr; S</i>, if all of the following
+   * conditions are met:
+   * <ul>
+   * <li>Either
+   * <ul>
+   * <li><i>S</i> is void, or</li>
+   * <li><i>T &hArr; S</i>.</li>
+   * </ul>
+   * </li>
+   * <li>For all <i>i</i>, 1 <= <i>i</i> <= <i>n</i>, <i>T<sub>i</sub> &hArr; S<sub>i</sub></i>.</li>
+   * </ul>
+   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, [T<sub>n+1</sub>, &hellip;,
+   * T<sub>n+k</sub>]) &rarr; T</i> is a subtype of the function type <i>(S<sub>1</sub>, &hellip;,
+   * S<sub>n</sub>, [S<sub>n+1</sub>, &hellip;, S<sub>n+m</sub>]) &rarr; S</i>, if all of the
+   * following conditions are met:
+   * <ul>
+   * <li>Either
+   * <ul>
+   * <li><i>S</i> is void, or</li>
+   * <li><i>T &hArr; S</i>.</li>
+   * </ul>
+   * </li>
+   * <li><i>k</i> >= <i>m</i> and for all <i>i</i>, 1 <= <i>i</i> <= <i>n+m</i>, <i>T<sub>i</sub>
+   * &hArr; S<sub>i</sub></i>.</li>
+   * </ul>
+   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {T<sub>x1</sub> x1, &hellip;,
+   * T<sub>xk</sub> xk}) &rarr; T</i> is a subtype of the function type <i>(S<sub>1</sub>, &hellip;,
+   * S<sub>n</sub>, {S<sub>y1</sub> y1, &hellip;, S<sub>ym</sub> ym}) &rarr; S</i>, if all of the
+   * following conditions are met:
+   * <ul>
+   * <li>Either
+   * <ul>
+   * <li><i>S</i> is void,</li>
+   * <li>or <i>T &hArr; S</i>.</li>
+   * </ul>
+   * </li>
+   * <li>For all <i>i</i>, 1 <= <i>i</i> <= <i>n</i>, <i>T<sub>i</sub> &hArr; S<sub>i</sub></i>.</li>
+   * <li><i>k</i> >= <i>m</i> and <i>y<sub>i</sub></i> in <i>{x<sub>1</sub>, &hellip;,
+   * x<sub>k</sub>}</i>, 1 <= <i>i</i> <= <i>m</i>.</li>
+   * <li>For all <i>y<sub>i</sub></i> in <i>{y<sub>1</sub>, &hellip;, y<sub>m</sub>}</i>,
+   * <i>y<sub>i</sub> = x<sub>j</sub> => Tj &hArr; Si</i>.</li>
+   * </ul>
+   * In addition, the following subtype rules apply:
+   * <p>
+   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, []) &rarr; T <: (T<sub>1</sub>, &hellip;,
+   * T<sub>n</sub>) &rarr; T.</i><br>
+   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T <: (T<sub>1</sub>, &hellip;,
+   * T<sub>n</sub>, {}) &rarr; T.</i><br>
+   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {}) &rarr; T <: (T<sub>1</sub>, &hellip;,
+   * T<sub>n</sub>) &rarr; T.</i><br>
+   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T <: (T<sub>1</sub>, &hellip;,
+   * T<sub>n</sub>, []) &rarr; T.</i>
+   * <p>
+   * All functions implement the class {@code Function}. However not all function types are a
+   * subtype of {@code Function}. If an interface type <i>I</i> includes a method named{@code call()}, and the type of {@code call()} is the function type <i>F</i>, then <i>I</i> is
+   * considered to be a subtype of <i>F</i>.
+   * @param type the type being compared with this type
+   * @return {@code true} if this type is a subtype of the given type
+   */
+  bool isSubtypeOf(Type2 type);
+  /**
+   * Return the type resulting from substituting the given arguments for this type's parameters.
+   * This is fully equivalent to {@code substitute(argumentTypes, getTypeArguments())}.
+   * @param argumentTypes the actual type arguments being substituted for the type parameters
+   * @return the result of performing the substitution
+   */
+  FunctionType substitute4(List<Type2> argumentTypes);
+  FunctionType substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes);
+}
+/**
+ * The interface {@code InterfaceType} defines the behavior common to objects representing the type
+ * introduced by either a class or an interface, or a reference to such a type.
+ */
+abstract class InterfaceType implements Type2 {
+  ClassElement get element;
+  /**
+   * Return the least upper bound of this type and the given type, or {@code null} if there is no
+   * least upper bound.
+   * <p>
+   * Given two interfaces <i>I</i> and <i>J</i>, let <i>S<sub>I</sub></i> be the set of
+   * superinterfaces of <i>I<i>, let <i>S<sub>J</sub></i> be the set of superinterfaces of <i>J</i>
+   * and let <i>S = (I &cup; S<sub>I</sub>) &cap; (J &cup; S<sub>J</sub>)</i>. Furthermore, we
+   * define <i>S<sub>n</sub> = {T | T &isin; S &and; depth(T) = n}</i> for any finite <i>n</i>,
+   * where <i>depth(T)</i> is the number of steps in the longest inheritance path from <i>T</i> to
+   * <i>Object</i>. Let <i>q</i> be the largest number such that <i>S<sub>q</sub></i> has
+   * cardinality one. The least upper bound of <i>I</i> and <i>J</i> is the sole element of
+   * <i>S<sub>q</sub></i>.
+   * @param type the other type used to compute the least upper bound
+   * @return the least upper bound of this type and the given type
+   */
+  Type2 getLeastUpperBound(Type2 type);
+  /**
+   * Return the type representing the superclass of this type. Note that this is <b>not</b>, in
+   * general, equivalent to getting the superclass from this type's element because the type
+   * returned by this method will have had it's type parameters replaced.
+   * @return the superclass of this type
+   */
+  Type2 get superclass;
+  /**
+   * Return an array containing the actual types of the type arguments. If this type's element does
+   * not have type parameters, then the array should be empty (although it is possible for type
+   * arguments to be erroneously declared). If the element has type parameters and the actual type
+   * does not explicitly include argument values, then the type "dynamic" will be automatically
+   * provided.
+   * @return the actual types of the type arguments
+   */
+  List<Type2> get typeArguments;
+  /**
+   * Return {@code true} if this type is a direct supertype of the given type. The implicit
+   * interface of class <i>I</i> is a direct supertype of the implicit interface of class <i>J</i>
+   * iff:
+   * <ul>
+   * <li><i>I</i> is Object, and <i>J</i> has no extends clause.</li>
+   * <li><i>I</i> is listed in the extends clause of <i>J</i>.</li>
+   * <li><i>I</i> is listed in the implements clause of <i>J</i>.</li>
+   * <li><i>I</i> is listed in the with clause of <i>J</i>.</li>
+   * <li><i>J</i> is a mixin application of the mixin of <i>I</i>.</li>
+   * </ul>
+   * @param type the type being compared with this type
+   * @return {@code true} if this type is a direct supertype of the given type
+   */
+  bool isDirectSupertypeOf(InterfaceType type);
+  /**
+   * Return {@code true} if this type is more specific than the given type. An interface type
+   * <i>T</i> is more specific than an interface type <i>S</i>, written <i>T &laquo; S</i>, if one
+   * of the following conditions is met:
+   * <ul>
+   * <li>Reflexivity: <i>T</i> is <i>S</i>.
+   * <li><i>T</i> is bottom.
+   * <li><i>S</i> is dynamic.
+   * <li>Direct supertype: <i>S</i> is a direct supertype of <i>T</i>.
+   * <li><i>T</i> is a type variable and <i>S</i> is the upper bound of <i>T</i>.
+   * <li>Covariance: <i>T</i> is of the form <i>I&lt;T<sub>1</sub>, &hellip;, T<sub>n</sub>&gt;</i>
+   * and S</i> is of the form <i>I&lt;S<sub>1</sub>, &hellip;, S<sub>n</sub>&gt;</i> and
+   * <i>T<sub>i</sub> &laquo; S<sub>i</sub></i>, <i>1 <= i <= n</i>.
+   * <li>Transitivity: <i>T &laquo; U</i> and <i>U &laquo; S</i>.
+   * </ul>
+   * @param type the type being compared with this type
+   * @return {@code true} if this type is more specific than the given type
+   */
+  bool isMoreSpecificThan(Type2 type);
+  /**
+   * Return {@code true} if this type is a subtype of the given type. An interface type <i>T</i> is
+   * a subtype of an interface type <i>S</i>, written <i>T</i> <: <i>S</i>, iff
+   * <i>[bottom/dynamic]T</i> &laquo; <i>S</i> (<i>T</i> is more specific than <i>S</i>). If an
+   * interface type <i>I</i> includes a method named <i>call()</i>, and the type of <i>call()</i> is
+   * the function type <i>F</i>, then <i>I</i> is considered to be a subtype of <i>F</i>.
+   * @param type the type being compared with this type
+   * @return {@code true} if this type is a subtype of the given type
+   */
+  bool isSubtypeOf(Type2 type);
+  /**
+   * Return the type resulting from substituting the given arguments for this type's parameters.
+   * This is fully equivalent to {@code substitute(argumentTypes, getTypeArguments())}.
+   * @param argumentTypes the actual type arguments being substituted for the type parameters
+   * @return the result of performing the substitution
+   */
+  InterfaceType substitute5(List<Type2> argumentTypes);
+  InterfaceType substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes);
+}
+/**
+ * The interface {@code Type} defines the behavior of objects representing the declared type of
+ * elements in the element model.
+ */
+abstract class Type2 {
+  /**
+   * Return the element representing the declaration of this type, or {@code null} if the type has
+   * not, or cannot, be associated with an element. The former case will occur if the element model
+   * is not yet complete; the latter case will occur if this object represents an undefined type.
+   * @return the element representing the declaration of this type
+   */
+  Element get element;
+  /**
+   * Return the least upper bound of this type and the given type, or {@code null} if there is no
+   * least upper bound.
+   * @param type the other type used to compute the least upper bound
+   * @return the least upper bound of this type and the given type
+   */
+  Type2 getLeastUpperBound(Type2 type);
+  /**
+   * Return the name of this type, or {@code null} if the type does not have a name, such as when
+   * the type represents the type of an unnamed function.
+   * @return the name of this type
+   */
+  String get name;
+  /**
+   * Return {@code true} if this type is assignable to the given type. A type <i>T</i> may be
+   * assigned to a type <i>S</i>, written <i>T</i> &hArr; <i>S</i>, iff either <i>T</i> <: <i>S</i>
+   * or <i>S</i> <: <i>T</i>.
+   * @param type the type being compared with this type
+   * @return {@code true} if this type is assignable to the given type
+   */
+  bool isAssignableTo(Type2 type);
+  /**
+   * Return {@code true} if this type is more specific than the given type.
+   * @param type the type being compared with this type
+   * @return {@code true} if this type is more specific than the given type
+   */
+  bool isMoreSpecificThan(Type2 type);
+  /**
+   * Return {@code true} if this type is a subtype of the given type.
+   * @param type the type being compared with this type
+   * @return {@code true} if this type is a subtype of the given type
+   */
+  bool isSubtypeOf(Type2 type);
+  /**
+   * Return {@code true} if this type is a supertype of the given type. A type <i>S</i> is a
+   * supertype of <i>T</i>, written <i>S</i> :> <i>T</i>, iff <i>T</i> is a subtype of <i>S</i>.
+   * @param type the type being compared with this type
+   * @return {@code true} if this type is a supertype of the given type
+   */
+  bool isSupertypeOf(Type2 type);
+  /**
+   * Return the type resulting from substituting the given arguments for the given parameters in
+   * this type. The specification defines this operation in section 2: <blockquote> The notation
+   * <i>[x<sub>1</sub>, ..., x<sub>n</sub>/y<sub>1</sub>, ..., y<sub>n</sub>]E</i> denotes a copy of
+   * <i>E</i> in which all occurrences of <i>y<sub>i</sub>, 1 <= i <= n</i> have been replaced with
+   * <i>x<sub>i</sub></i>.</blockquote> Note that, contrary to the specification, this method will
+   * not create a copy of this type if no substitutions were required, but will return this type
+   * directly.
+   * @param argumentTypes the actual type arguments being substituted for the parameters
+   * @param parameterTypes the parameters to be replaced
+   * @return the result of performing the substitution
+   */
+  Type2 substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes);
+}
+/**
+ * The interface {@code TypeVariableType} defines the behavior of objects representing the type
+ * introduced by a type variable.
+ */
+abstract class TypeVariableType implements Type2 {
+  TypeVariableElement get element;
+}
+/**
+ * The interface {@code VoidType} defines the behavior of the unique object representing the type{@code void}.
+ */
+abstract class VoidType implements Type2 {
+  VoidType substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes);
+}
\ 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
new file mode 100644
index 0000000..b888255
--- /dev/null
+++ b/pkg/analyzer-experimental/lib/src/generated/error.dart
@@ -0,0 +1,229 @@
+// 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.error;
+
+import 'java_core.dart';
+import 'source.dart';
+
+/**
+ * Instances of the enumeration {@code ErrorType} represent the type of an {@link ErrorCode}.
+ */
+class ErrorType {
+  /**
+   * Compile-time errors are errors that preclude execution. A compile time error must be reported
+   * by a Dart compiler before the erroneous code is executed.
+   */
+  static final ErrorType COMPILE_TIME_ERROR = new ErrorType('COMPILE_TIME_ERROR', 0, ErrorSeverity.ERROR);
+  /**
+   * Static warnings are those warnings reported by the static checker. They have no effect on
+   * execution. Static warnings must be provided by Dart compilers used during development.
+   */
+  static final ErrorType STATIC_WARNING = new ErrorType('STATIC_WARNING', 1, ErrorSeverity.WARNING);
+  /**
+   * Many, but not all, static warnings relate to types, in which case they are known as static type
+   * warnings.
+   */
+  static final ErrorType STATIC_TYPE_WARNING = new ErrorType('STATIC_TYPE_WARNING', 2, ErrorSeverity.WARNING);
+  /**
+   * Syntactic errors are errors produced as a result of input that does not conform to the grammar.
+   */
+  static final ErrorType SYNTACTIC_ERROR = new ErrorType('SYNTACTIC_ERROR', 3, ErrorSeverity.ERROR);
+  static final List<ErrorType> values = [COMPILE_TIME_ERROR, STATIC_WARNING, STATIC_TYPE_WARNING, SYNTACTIC_ERROR];
+  final String __name;
+  final int __ordinal;
+  /**
+   * The severity of this type of error.
+   */
+  ErrorSeverity _severity;
+  /**
+   * Initialize a newly created error type to have the given severity.
+   * @param severity the severity of this type of error
+   */
+  ErrorType(this.__name, this.__ordinal, ErrorSeverity severity) {
+    this._severity = severity;
+  }
+  /**
+   * Return the severity of this type of error.
+   * @return the severity of this type of error
+   */
+  ErrorSeverity get severity => _severity;
+  String toString() => __name;
+}
+/**
+ * The interface {@code ErrorCode} defines the behavior common to objects representing error codes
+ * associated with {@link AnalysisError analysis errors}.
+ */
+abstract class ErrorCode {
+  /**
+   * Return the severity of this error.
+   * @return the severity of this error
+   */
+  ErrorSeverity get errorSeverity;
+  /**
+   * Return the message template used to create the message to be displayed for this error.
+   * @return the message template used to create the message to be displayed for this error
+   */
+  String get message;
+  /**
+   * Return the type of the error.
+   * @return the type of the error
+   */
+  ErrorType get type;
+  /**
+   * Return {@code true} if this error should cause recompilation of the source during the next
+   * incremental compilation.
+   * @return {@code true} if this error should cause recompilation of the source during the next
+   * incremental compilation
+   */
+  bool needsRecompilation();
+}
+/**
+ * Instances of the enumeration {@code ErrorSeverity} represent the severity of an {@link ErrorCode}.
+ */
+class ErrorSeverity {
+  /**
+   * The severity representing an error.
+   */
+  static final ErrorSeverity ERROR = new ErrorSeverity('ERROR', 0, "E");
+  /**
+   * The severity representing a warning. Warnings can become errors if the {@code -Werror} command
+   * line flag is specified.
+   */
+  static final ErrorSeverity WARNING = new ErrorSeverity('WARNING', 1, "W");
+  static final List<ErrorSeverity> values = [ERROR, WARNING];
+  final String __name;
+  final int __ordinal;
+  String _name;
+  ErrorSeverity(this.__name, this.__ordinal, String name) {
+    this._name = name;
+  }
+  String get name => _name;
+  String toString() => __name;
+}
+/**
+ * The interface {@code AnalysisErrorListener} defines the behavior of objects that listen for{@link AnalysisError analysis errors} being produced by the analysis engine.
+ */
+abstract class AnalysisErrorListener {
+  /**
+   * This method is invoked when an error has been found by the analysis engine.
+   * @param error the error that was just found (not {@code null})
+   */
+  void onError(AnalysisError error);
+}
+/**
+ * Instances of the class {@code AnalysisError} represent an error discovered during the analysis of
+ * some Dart code.
+ * @see AnalysisErrorListener
+ */
+class AnalysisError {
+  /**
+   * An empty array of errors used when no errors are expected.
+   */
+  static List<AnalysisError> NO_ERRORS = new List<AnalysisError>.fixedLength(0);
+  /**
+   * The error code associated with the error.
+   */
+  ErrorCode _errorCode;
+  /**
+   * The localized error message.
+   */
+  String _message;
+  /**
+   * The source in which the error occurred, or {@code null} if unknown.
+   */
+  Source _source;
+  /**
+   * The character offset from the beginning of the source (zero based) where the error occurred.
+   */
+  int _offset = 0;
+  /**
+   * The number of characters from the offset to the end of the source which encompasses the
+   * compilation error.
+   */
+  int _length = 0;
+  /**
+   * Initialize a newly created analysis error for the specified source. The error has no location
+   * information.
+   * @param source the source for which the exception occurred
+   * @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);
+  }
+  _jtd_constructor_117_impl(Source source, ErrorCode errorCode, List<Object> arguments) {
+    this._source = source;
+    this._errorCode = errorCode;
+    this._message = JavaString.format(errorCode.message, arguments);
+  }
+  /**
+   * Initialize a newly created analysis error for the specified source at the given location.
+   * @param source the source for which the exception occurred
+   * @param offset the offset of the location of the error
+   * @param length the length of the location of the error
+   * @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);
+  }
+  _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);
+  }
+  /**
+   * Return the error code associated with the error.
+   * @return the error code associated with the error
+   */
+  ErrorCode get errorCode => _errorCode;
+  /**
+   * Return the number of characters from the offset to the end of the source which encompasses the
+   * compilation error.
+   * @return the length of the error location
+   */
+  int get length => _length;
+  /**
+   * Return the localized error message.
+   * @return the localized error message
+   */
+  String get message => _message;
+  /**
+   * Return the character offset from the beginning of the source (zero based) where the error
+   * occurred.
+   * @return the offset to the start of the error location
+   */
+  int get offset => _offset;
+  /**
+   * Return the source in which the error occurred, or {@code null} if unknown.
+   * @return the source in which the error occurred
+   */
+  Source get source => _source;
+  int get hashCode {
+    int hashCode = _offset;
+    hashCode ^= (_message != null) ? _message.hashCode : 0;
+    hashCode ^= (_source != null) ? _source.hashCode : 0;
+    return hashCode;
+  }
+  /**
+   * 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;
+  }
+  String toString() {
+    StringBuffer builder = new StringBuffer();
+    builder.add((_source != null) ? _source.fullName : "<unknown source>");
+    builder.add("(");
+    builder.add(_offset);
+    builder.add("..");
+    builder.add(_offset + _length - 1);
+    builder.add("): ");
+    builder.add(_message);
+    return builder.toString();
+  }
+}
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/lib/src/generated/instrumentation.dart b/pkg/analyzer-experimental/lib/src/generated/instrumentation.dart
new file mode 100644
index 0000000..6083629
--- /dev/null
+++ b/pkg/analyzer-experimental/lib/src/generated/instrumentation.dart
@@ -0,0 +1,189 @@
+// 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.instrumentation;
+
+import 'java_core.dart';
+
+/**
+ * The interface {@code OperationBuilder} defines the behavior of objects used to collect data about
+ * an operation that has occurred and record that data through an instrumentation logger.
+ * <p>
+ * For an example of using objects that implement this interface, see {@link Instrumentation}.
+ */
+abstract class OperationBuilder {
+  /**
+   * Log the data that has been collected. The operation builder should not be used after this
+   * method is invoked. The behavior of any method defined on this interface that is used after this
+   * method is invoked is undefined.
+   */
+  void log();
+  /**
+   * Lazily compute and append the given data to the data being collected by this builder.
+   * @param name the name used to identify the data
+   * @param a function that will be executed in the background to return the value of the data to be
+   * collected
+   * @return this builder
+   */
+  OperationBuilder with2(String name, AsyncValue valueGenerator);
+  /**
+   * Append the given data to the data being collected by this builder.
+   * @param name the name used to identify the data
+   * @param value the value of the data to be collected
+   * @return this builder
+   */
+  OperationBuilder with3(String name, int value);
+  /**
+   * Append the given data to the data being collected by this builder.
+   * @param name the name used to identify the data
+   * @param value the value of the data to be collected
+   * @return this builder
+   */
+  OperationBuilder with4(String name, String value);
+  /**
+   * Append the given data to the data being collected by this builder.
+   * @param name the name used to identify the data
+   * @param value the value of the data to be collected
+   * @return this builder
+   */
+  OperationBuilder with5(String name, List<String> value);
+}
+/**
+ * The interface {@code InstrumentationLogger} defines the behavior of objects that are used to log
+ * instrumentation data.
+ * <p>
+ * For an example of using objects that implement this interface, see {@link Instrumentation}.
+ */
+abstract class InstrumentationLogger {
+  /**
+   * Create an operation builder that can collect the data associated with an operation. The
+   * operation is identified by the given name, is declared to contain only metrics data (data that
+   * is not user identifiable and does not contain user intellectual property), and took the given
+   * amount of time to complete.
+   * @param name the name used to uniquely identify the operation
+   * @param time the number of milliseconds required to perform the operation, or {@code -1} if the
+   * time is not available or not applicable to this kind of operation
+   * @return the operation builder that was created
+   */
+  OperationBuilder createMetric(String name, int time);
+  /**
+   * Create an operation builder that can collect the data associated with an operation. The
+   * operation is identified by the given name, is declared to potentially contain data that is
+   * either user identifiable or contains user intellectual property (but is not guaranteed to
+   * contain either), and took the given amount of time to complete.
+   * @param name the name used to uniquely identify the operation
+   * @param time the number of milliseconds required to perform the operation, or {@code -1} if the
+   * time is not available or not applicable to this kind of operation
+   * @return the operation builder that was created
+   */
+  OperationBuilder createOperation(String name, int time);
+}
+abstract class AsyncValue {
+  /**
+   * Returns a String to be logged This would typically be used with an anonymous implementation
+   * closing over some variables with an expensive operation to be performed in the background
+   * @return The data to be logged
+   */
+  String compute();
+}
+/**
+ * The class {@code Instrumentation} implements support for logging instrumentation information.
+ * <p>
+ * Instrumentation information consists of information about specific operations. Those operations
+ * can range from user-facing operations, such as saving the changes to a file, to internal
+ * operations, such as tokenizing source code. The information to be logged is gathered by an{@link OperationBuilder operation builder}, created by one of the static methods on this class.
+ * <p>
+ * Note, however, that until an instrumentation logger is installed using the method{@link #setLogger(InstrumentationLogger)}, all instrumentation data will be lost.
+ * <p>
+ * <b>Example</b>
+ * <p>
+ * To collect metrics about how long it took to save a file, you would write something like the
+ * following:
+ * <pre>
+ * long startTime = System.currentTimeMillis();
+ * // save the file
+ * long endTime = System.currentTimeMillis();
+ * metric("Save", endTime - startTime).with("chars", fileLength).log();
+ * </pre>
+ * The {@code metric} method creates an operation builder for an operation named {@code "Save"} that
+ * took {@code endTime - startTime} milliseconds to run. The {@code with} method attaches additional
+ * data to the operation; in this case recording that the file was {@code fileLength} characters
+ * long. The {@code log} method tells the builder that all of the data has been collected and that
+ * the resulting information should be logged.
+ */
+class Instrumentation {
+  /**
+   * 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();
+  /**
+   * The current instrumentation logger.
+   */
+  static InstrumentationLogger _CURRENT_LOGGER = _NULL_LOGGER;
+  /**
+   * Create an operation builder that can collect the data associated with an operation. The
+   * operation is identified by the given name and is declared to contain only metrics data (data
+   * that is not user identifiable and does not contain user intellectual property).
+   * @param name the name used to uniquely identify the operation
+   * @return the operation builder that was created
+   */
+  static OperationBuilder metric(String name) => _CURRENT_LOGGER.createMetric(name, -1);
+  /**
+   * Create an operation builder that can collect the data associated with an operation. The
+   * operation is identified by the given name, is declared to contain only metrics data (data that
+   * is not user identifiable and does not contain user intellectual property), and took the given
+   * amount of time to complete.
+   * @param name the name used to uniquely identify the operation
+   * @param time the number of milliseconds required to perform the operation
+   * @return the operation builder that was created
+   */
+  static OperationBuilder metric2(String name, int time) => _CURRENT_LOGGER.createMetric(name, time);
+  /**
+   * Create an operation builder that can collect the data associated with an operation. The
+   * operation is identified by the given name and is declared to potentially contain data that is
+   * either user identifiable or contains user intellectual property (but is not guaranteed to
+   * contain either).
+   * @param name the name used to uniquely identify the operation
+   * @return the operation builder that was created
+   */
+  static OperationBuilder operation(String name) => _CURRENT_LOGGER.createOperation(name, -1);
+  /**
+   * Create an operation builder that can collect the data associated with an operation. The
+   * operation is identified by the given name, is declared to potentially contain data that is
+   * either user identifiable or contains user intellectual property (but is not guaranteed to
+   * contain either), and took the given amount of time to complete.
+   * @param name the name used to uniquely identify the operation
+   * @param time the number of milliseconds required to perform the operation
+   * @return the operation builder that was created
+   */
+  static OperationBuilder operation2(String name, int time) => _CURRENT_LOGGER.createOperation(name, time);
+  /**
+   * 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;
+  }
+  /**
+   * Prevent the creation of instances of this class
+   */
+  Instrumentation() {
+  }
+}
+class InstrumentationLogger_2 implements InstrumentationLogger {
+  /**
+   * An operation builder that will silently ignore all data and logging requests.
+   */
+  OperationBuilder _NULL_BUILDER = new OperationBuilder_3();
+  OperationBuilder createMetric(String name, int time) => _NULL_BUILDER;
+  OperationBuilder createOperation(String name, int time) => _NULL_BUILDER;
+}
+class OperationBuilder_3 implements OperationBuilder {
+  void log() {
+  }
+  OperationBuilder with2(String name, AsyncValue valueGenerator) => this;
+  OperationBuilder with3(String name, int value) => this;
+  OperationBuilder with4(String name, String value) => this;
+  OperationBuilder with5(String name, List<String> value) => this;
+}
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/lib/src/generated/java_core.dart b/pkg/analyzer-experimental/lib/src/generated/java_core.dart
new file mode 100644
index 0000000..25c8862
--- /dev/null
+++ b/pkg/analyzer-experimental/lib/src/generated/java_core.dart
@@ -0,0 +1,301 @@
+library java.core;
+
+import "dart:math" as math;
+
+class System {
+  static int currentTimeMillis() {
+    return (new Date.now()).millisecondsSinceEpoch;
+  }
+}
+
+/**
+ * Limited implementation of "o is instanceOfType", see
+ * http://code.google.com/p/dart/issues/detail?id=8184
+ */
+bool isInstanceOf(o, Type t) {
+  if (o == null) {
+    return false;
+  }
+  if (o.runtimeType == t) {
+    return true;
+  }
+  String oTypeName = o.runtimeType.toString();
+  if (oTypeName == "${t.toString()}Impl") {
+    return true;
+  }
+  return false;
+}
+
+class JavaArrays {
+  static bool equals(List a, List b) {
+    if (a.length != b.length) {
+      return false;
+    }
+    var len = a.length;
+    for (int i = 0; i < len; i++) {
+      if (a[i] != b[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+  static int makeHashCode(List a) {
+    if (a == null) {
+      return 0;
+    }
+    int result = 1;
+    for (var element in a) {
+      result = 31 * result + (element == null ? 0 : element.hashCode());
+    }
+    return result;
+  }
+}
+
+class Character {
+  static const int MAX_VALUE = 0xffff;
+  static const int MAX_CODE_POINT = 0x10ffff;
+  static bool isLetter(int c) {
+    return c >= 0x41 && c <= 0x5A || c >= 0x61 && c <= 0x7A;
+  }
+  static bool isLetterOrDigit(int c) {
+    return isLetter(c) || c >= 0x30 && c <= 0x39;
+  }
+  static int digit(int codePoint, int radix) {
+    if (radix != 16) {
+      throw new ArgumentError("only radix == 16 is supported");
+    }
+    if (0x30 <= codePoint && codePoint <= 0x39) {
+      return codePoint - 0x30;
+    }
+    if (0x41 <= codePoint && codePoint <= 0x46) {
+      return 0xA + (codePoint - 0x41);
+    }
+  }
+  static String toChars(int codePoint) {
+    throw new UnsupportedOperationException();
+  }
+}
+
+class CharBuffer {
+  final String _content;
+  CharBuffer(this._content);
+  static CharBuffer wrap(String content) => new CharBuffer(content);
+  int charAt(int index) => _content.charCodeAt(index);
+  int length() => _content.length;
+  String subSequence(int start, int end) => _content.substring(start, end);
+}
+
+class JavaString {
+  static String format(String fmt, List args) {
+    return fmt;
+  }
+}
+
+/**
+ * Very limited printf implementation, supports only %s and %d.
+ */
+String _printf(String fmt, List args) {
+  StringBuffer sb = new StringBuffer();
+  bool markFound = false;
+  int argIndex = 0;
+  for (int i = 0; i < fmt.length; i++) {
+    int c = fmt.charCodeAt(i);
+    if (c == 0x25) {
+      if (markFound) {
+        sb.addCharCode(c);
+        markFound = false;
+      } else {
+        markFound = true;
+      }
+      continue;
+    }
+    if (markFound) {
+      markFound = false;
+      // %d
+      if (c == 0x64) {
+        sb.add(args[argIndex++]);
+        continue;
+      }
+      // %s
+      if (c == 0x73) {
+        sb.add(args[argIndex++]);
+        continue;
+      }
+      // unknown
+      throw new IllegalArgumentException('[$fmt][$i] = 0x${c.toRadixString(16)}');
+    } else {
+      sb.addCharCode(c);
+    }
+  }
+  return sb.toString();
+}
+
+abstract class PrintWriter {
+  void print(x);
+
+  void println() {
+    this.print('\n');
+  }
+
+  void printlnObject(String s) {
+    this.print(s);
+    this.println();
+  }
+
+  void printf(String fmt, List args) {
+    this.print(_printf(fmt, args));
+  }
+}
+
+class PrintStringWriter extends PrintWriter {
+  final StringBuffer _sb = new StringBuffer();
+
+  void print(x) {
+    _sb.add(x);
+  }
+
+  String toString() => _sb.toString();
+}
+
+class StringUtils {
+  static List<String> split(String s, String pattern) => s.split(pattern);
+  static String replace(String s, String from, String to) => s.replaceAll(from, to);
+  static String repeat(String s, int n) {
+    StringBuffer sb = new StringBuffer();
+    for (int i = 0; i < n; i++) {
+      sb.add(s);
+    }
+    return sb.toString();
+  }
+}
+
+class Math {
+  static num max(num a, num b) => math.max(a, b);
+  static num min(num a, num b) => math.min(a, b);
+}
+
+class RuntimeException implements Exception {
+  String toString() => "RuntimeException";
+}
+
+class IllegalArgumentException implements Exception {
+  final String message;
+  const IllegalArgumentException([this.message = ""]);
+  String toString() => "IllegalStateException: $message";
+}
+
+class IllegalStateException implements Exception {
+  final String message;
+  const IllegalStateException([this.message = ""]);
+  String toString() => "IllegalStateException: $message";
+}
+
+class UnsupportedOperationException implements Exception {
+  String toString() => "UnsupportedOperationException";
+}
+
+class NumberFormatException implements Exception {
+  String toString() => "NumberFormatException";
+}
+
+class ListWrapper<E> extends Collection<E> implements List<E> {
+  List<E> elements = new List<E>();
+
+  Iterator<E> get iterator {
+    return elements.iterator;
+  }
+
+  E operator [](int index) {
+    return elements[index];
+  }
+
+  void operator []=(int index, E value) {
+    elements[index] = value;
+  }
+
+  void set length(int newLength) {
+    elements.length = newLength;
+  }
+
+  void add(E value) {
+    elements.add(value);
+  }
+
+  void addLast(E value) {
+    elements.addLast(value);
+  }
+
+  void addAll(Iterable<E> iterable) {
+    elements.addAll(iterable);
+  }
+
+  void sort([int compare(E a, E b)]) {
+    elements.sort(compare);
+  }
+
+  int indexOf(E element, [int start = 0]) {
+    return elements.indexOf(element, start);
+  }
+
+  int lastIndexOf(E element, [int start]) {
+    return elements.lastIndexOf(element, start);
+  }
+
+  void clear() {
+    elements.clear();
+  }
+
+  void remove(Object element) {
+    return elements.remove(element);
+  }
+
+  E removeAt(int index) {
+    return elements.removeAt(index);
+  }
+
+  E removeLast() {
+    return elements.removeLast();
+  }
+
+  List<E> get reversed => elements.reversed;
+
+  List<E> getRange(int start, int length) {
+    return elements.getRange(start, length);
+  }
+
+  void setRange(int start, int length, List<E> from, [int startFrom]) {
+    elements.setRange(start, length, from, startFrom);
+  }
+
+  void removeRange(int start, int length) {
+    elements.removeRange(start, length);
+  }
+
+  void insertRange(int start, int length, [E fill]) {
+    elements.insertRange(start, length, fill);
+  }
+}
+
+class MapEntry<K, V> {
+  K _key;
+  V _value;
+  MapEntry(this._key, this._value);
+  K getKey() => _key;
+  V getValue() => _value;
+}
+
+Set<MapEntry> getMapEntrySet(Map m) {
+  Set<MapEntry> result = new Set();
+  m.forEach((k, v) {
+    result.add(new MapEntry(k, v));
+  });
+  return result;
+}
+
+bool javaSetAdd(Set s, o) {
+  if (!s.contains(o)) {
+    s.add(o);
+    return true;
+  }
+  return false;
+}
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/lib/src/generated/java_engine.dart b/pkg/analyzer-experimental/lib/src/generated/java_engine.dart
new file mode 100644
index 0000000..9a0c265
--- /dev/null
+++ b/pkg/analyzer-experimental/lib/src/generated/java_engine.dart
@@ -0,0 +1,48 @@
+library java.engine;
+
+import "java_core.dart";
+import "source.dart";
+import "error.dart";
+import "ast.dart";
+import "element.dart";
+
+class AnalysisException implements Exception {
+  String toString() => "AnalysisException";
+}
+
+class AnalysisEngine {
+  static getInstance() {
+    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 StringUtilities {
+  static List<String> EMPTY_ARRAY = new List.fixedLength(0);
+}
diff --git a/pkg/analyzer-experimental/lib/src/generated/java_junit.dart b/pkg/analyzer-experimental/lib/src/generated/java_junit.dart
new file mode 100644
index 0000000..62879bc
--- /dev/null
+++ b/pkg/analyzer-experimental/lib/src/generated/java_junit.dart
@@ -0,0 +1,109 @@
+library java.junit;
+
+import 'package:unittest/unittest.dart' hide fail;
+import 'package:unittest/unittest.dart' as _ut show fail;
+
+
+class JUnitTestCase {
+  void setUp() {}
+  void tearDown() {}
+  static void fail(String msg) {
+    _ut.fail(msg);
+  }
+  static void assertTrue(bool x) {
+    expect(x, isTrue);
+  }
+  static void assertTrueMsg(String msg, bool x) {
+    expect(x, isTrueMsg(msg));
+  }
+  static void assertFalse(bool x) {
+    expect(x, isFalse);
+  }
+  static void assertFalseMsg(String msg, bool x) {
+    expect(x, isFalseMsg(msg));
+  }
+  static void assertNull(x) {
+    expect(x, isNull);
+  }
+  static void assertNotNull(x) {
+    expect(x, isNotNull);
+  }
+  static void assertEquals(expected, actual) {
+    expect(actual, equals(expected));
+  }
+  static void assertEqualsMsg(String msg, expected, actual) {
+    expect(actual, equalsMsg(msg, expected));
+  }
+}
+
+runJUnitTest(testInstance, Function testFunction) {
+  testInstance.setUp();
+  try {
+    testFunction();
+  } finally {
+    testInstance.tearDown();
+  }
+}
+
+/**
+ * Returns a matches that matches if the value is not the same instance
+ * as [object] (`!==`).
+ */
+Matcher notSame(expected) => new _IsNotSameAs(expected);
+
+class _IsNotSameAs extends BaseMatcher {
+  final _expected;
+  const _IsNotSameAs(this._expected);
+  bool matches(item, MatchState matchState) => !identical(item, _expected);
+  Description describe(Description description) =>
+      description.add('not same instance as ').addDescriptionOf(_expected);
+}
+
+Matcher equalsMsg(String msg, expected) => new _EqualsWithMessage(msg, expected);
+class _EqualsWithMessage extends BaseMatcher {
+  final String msg;
+  final expectedValue;
+  const _EqualsWithMessage(this.msg, this.expectedValue);
+  bool matches(item, MatchState matchState) {
+    return item == expectedValue;
+  }
+  Description describe(Description mismatchDescription) {
+    return mismatchDescription.replace(msg);
+  }
+  Description describeMismatch(item, Description mismatchDescription,
+                               MatchState matchState, bool verbose) {
+    return mismatchDescription.replace(msg).add(" $item != $expectedValue");
+  }
+}
+
+Matcher isTrueMsg(String msg) => new _IsTrueWithMessage(msg);
+class _IsTrueWithMessage extends BaseMatcher {
+  final String msg;
+  const _IsTrueWithMessage(this.msg);
+  bool matches(item, MatchState matchState) {
+    return item == true;
+  }
+  Description describe(Description mismatchDescription) {
+    return mismatchDescription.replace(msg);
+  }
+  Description describeMismatch(item, Description mismatchDescription,
+                               MatchState matchState, bool verbose) {
+    return mismatchDescription.replace(msg).add(" $item is not true");
+  }
+}
+
+Matcher isFalseMsg(String msg) => new _IsFalseWithMessage(msg);
+class _IsFalseWithMessage extends BaseMatcher {
+  final String msg;
+  const _IsFalseWithMessage(this.msg);
+  bool matches(item, MatchState matchState) {
+    return item == false;
+  }
+  Description describe(Description mismatchDescription) {
+    return mismatchDescription.replace(msg);
+  }
+  Description describeMismatch(item, Description mismatchDescription,
+                               MatchState matchState, bool verbose) {
+    return mismatchDescription.replace(msg).add(" $item is not false");
+  }
+}
diff --git a/pkg/analyzer-experimental/lib/src/generated/parser.dart b/pkg/analyzer-experimental/lib/src/generated/parser.dart
new file mode 100644
index 0000000..007f82f
--- /dev/null
+++ b/pkg/analyzer-experimental/lib/src/generated/parser.dart
@@ -0,0 +1,5649 @@
+// 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.parser;
+
+import 'dart:collection';
+import 'java_core.dart';
+import 'java_engine.dart';
+import 'error.dart';
+import 'source.dart';
+import 'scanner.dart';
+import 'ast.dart';
+import 'package:analyzer-experimental/src/generated/utilities_dart.dart';
+
+/**
+ * Instances of the class {@code CommentAndMetadata} implement a simple data-holder for a method
+ * that needs to return multiple values.
+ */
+class CommentAndMetadata {
+  /**
+   * The documentation comment that was parsed, or {@code null} if none was given.
+   */
+  Comment _comment;
+  /**
+   * The metadata that was parsed.
+   */
+  List<Annotation> _metadata;
+  /**
+   * Initialize a newly created holder with the given data.
+   * @param comment the documentation comment that was parsed
+   * @param metadata the metadata that was parsed
+   */
+  CommentAndMetadata(Comment comment, List<Annotation> metadata) {
+    this._comment = comment;
+    this._metadata = metadata;
+  }
+  /**
+   * Return the documentation comment that was parsed, or {@code null} if none was given.
+   * @return the documentation comment that was parsed
+   */
+  Comment get comment => _comment;
+  /**
+   * Return the metadata that was parsed. If there was no metadata, then the list will be empty.
+   * @return the metadata that was parsed
+   */
+  List<Annotation> get metadata => _metadata;
+}
+/**
+ * Instances of the class {@code FinalConstVarOrType} implement a simple data-holder for a method
+ * that needs to return multiple values.
+ */
+class FinalConstVarOrType {
+  /**
+   * The 'final', 'const' or 'var' keyword, or {@code null} if none was given.
+   */
+  Token _keyword;
+  /**
+   * The type, of {@code null} if no type was specified.
+   */
+  TypeName _type;
+  /**
+   * Initialize a newly created holder with the given data.
+   * @param keyword the 'final', 'const' or 'var' keyword
+   * @param type the type
+   */
+  FinalConstVarOrType(Token keyword, TypeName type) {
+    this._keyword = keyword;
+    this._type = type;
+  }
+  /**
+   * Return the 'final', 'const' or 'var' keyword, or {@code null} if none was given.
+   * @return the 'final', 'const' or 'var' keyword
+   */
+  Token get keyword => _keyword;
+  /**
+   * Return the type, of {@code null} if no type was specified.
+   * @return the type
+   */
+  TypeName get type => _type;
+}
+/**
+ * Instances of the class {@code Modifiers} implement a simple data-holder for a method that needs
+ * to return multiple values.
+ */
+class Modifiers {
+  /**
+   * The token representing the keyword 'abstract', or {@code null} if the keyword was not found.
+   */
+  Token _abstractKeyword;
+  /**
+   * The token representing the keyword 'const', or {@code null} if the keyword was not found.
+   */
+  Token _constKeyword;
+  /**
+   * The token representing the keyword 'external', or {@code null} if the keyword was not found.
+   */
+  Token _externalKeyword;
+  /**
+   * The token representing the keyword 'factory', or {@code null} if the keyword was not found.
+   */
+  Token _factoryKeyword;
+  /**
+   * The token representing the keyword 'final', or {@code null} if the keyword was not found.
+   */
+  Token _finalKeyword;
+  /**
+   * The token representing the keyword 'static', or {@code null} if the keyword was not found.
+   */
+  Token _staticKeyword;
+  /**
+   * The token representing the keyword 'var', or {@code null} if the keyword was not found.
+   */
+  Token _varKeyword;
+  /**
+   * Initialize a newly created and empty set of modifiers.
+   */
+  Modifiers() : super() {
+  }
+  /**
+   * Return the token representing the keyword 'abstract', or {@code null} if the keyword was not
+   * found.
+   * @return the token representing the keyword 'abstract'
+   */
+  Token get abstractKeyword => _abstractKeyword;
+  /**
+   * Return the token representing the keyword 'const', or {@code null} if the keyword was not
+   * found.
+   * @return the token representing the keyword 'const'
+   */
+  Token get constKeyword => _constKeyword;
+  /**
+   * Return the token representing the keyword 'external', or {@code null} if the keyword was not
+   * found.
+   * @return the token representing the keyword 'external'
+   */
+  Token get externalKeyword => _externalKeyword;
+  /**
+   * Return the token representing the keyword 'factory', or {@code null} if the keyword was not
+   * found.
+   * @return the token representing the keyword 'factory'
+   */
+  Token get factoryKeyword => _factoryKeyword;
+  /**
+   * Return the token representing the keyword 'final', or {@code null} if the keyword was not
+   * found.
+   * @return the token representing the keyword 'final'
+   */
+  Token get finalKeyword => _finalKeyword;
+  /**
+   * Return the token representing the keyword 'static', or {@code null} if the keyword was not
+   * found.
+   * @return the token representing the keyword 'static'
+   */
+  Token get staticKeyword => _staticKeyword;
+  /**
+   * Return the token representing the keyword 'var', or {@code null} if the keyword was not found.
+   * @return the token representing the keyword 'var'
+   */
+  Token get varKeyword => _varKeyword;
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  /**
+   * 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;
+  }
+  String toString() {
+    StringBuffer builder = new StringBuffer();
+    bool needsSpace = appendKeyword(builder, false, _abstractKeyword);
+    needsSpace = appendKeyword(builder, needsSpace, _constKeyword);
+    needsSpace = appendKeyword(builder, needsSpace, _externalKeyword);
+    needsSpace = appendKeyword(builder, needsSpace, _factoryKeyword);
+    needsSpace = appendKeyword(builder, needsSpace, _finalKeyword);
+    needsSpace = appendKeyword(builder, needsSpace, _staticKeyword);
+    appendKeyword(builder, needsSpace, _varKeyword);
+    return builder.toString();
+  }
+  /**
+   * If the given keyword is not {@code null}, append it to the given builder, prefixing it with a
+   * space if needed.
+   * @param builder the builder to which the keyword will be appended
+   * @param needsSpace {@code true} if the keyword needs to be prefixed with a space
+   * @param keyword the keyword to be appended
+   * @return {@code true} if subsequent keywords need to be prefixed with a space
+   */
+  bool appendKeyword(StringBuffer builder, bool needsSpace, Token keyword) {
+    if (keyword != null) {
+      if (needsSpace) {
+        builder.addCharCode(0x20);
+      }
+      builder.add(keyword.lexeme);
+      return true;
+    }
+    return needsSpace;
+  }
+}
+/**
+ * Instances of the class {@code Parser} are used to parse tokens into an AST structure.
+ */
+class Parser {
+  /**
+   * The source being parsed.
+   */
+  Source _source;
+  /**
+   * The error listener that will be informed of any errors that are found during the parse.
+   */
+  AnalysisErrorListener _errorListener;
+  /**
+   * The next token to be parsed.
+   */
+  Token _currentToken;
+  /**
+   * A flag indicating whether the parser is currently in the body of a loop.
+   */
+  bool _inLoop = false;
+  /**
+   * A flag indicating whether the parser is currently in a switch statement.
+   */
+  bool _inSwitch = false;
+  static String _HIDE = "hide";
+  static String _OF = "of";
+  static String _ON = "on";
+  static String _SHOW = "show";
+  /**
+   * Initialize a newly created parser.
+   * @param source the source being parsed
+   * @param errorListener the error listener that will be informed of any errors that are found
+   * during the parse
+   */
+  Parser(Source source, AnalysisErrorListener errorListener) {
+    this._source = source;
+    this._errorListener = errorListener;
+  }
+  /**
+   * Parse a compilation unit, starting with the given token.
+   * @param token the first token of the compilation unit
+   * @return the compilation unit that was parsed
+   */
+  CompilationUnit parseCompilationUnit(Token token) {
+    _currentToken = token;
+    return parseCompilationUnit2();
+  }
+  /**
+   * Parse an expression, starting with the given token.
+   * @param token the first token of the expression
+   * @return the expression that was parsed, or {@code null} if the tokens do not represent a
+   * recognizable expression
+   */
+  Expression parseExpression(Token token) {
+    _currentToken = token;
+    return parseExpression2();
+  }
+  /**
+   * Parse a statement, starting with the given token.
+   * @param token the first token of the statement
+   * @return the statement that was parsed, or {@code null} if the tokens do not represent a
+   * recognizable statement
+   */
+  Statement parseStatement(Token token) {
+    _currentToken = token;
+    return parseStatement2();
+  }
+  /**
+   * Parse a sequence of statements, starting with the given token.
+   * @param token the first token of the sequence of statement
+   * @return the statements that were parsed, or {@code null} if the tokens do not represent a
+   * recognizable sequence of statements
+   */
+  List<Statement> parseStatements(Token token) {
+    _currentToken = token;
+    return parseStatements2();
+  }
+  void set currentToken(Token currentToken) {
+    this._currentToken = currentToken;
+  }
+  /**
+   * Advance to the next token in the token stream.
+   */
+  void advance() {
+    _currentToken = _currentToken.next;
+  }
+  /**
+   * Append the character equivalent of the given scalar value to the given builder. Use the start
+   * and end indices to report an error, and don't append anything to the builder, if the scalar
+   * value is invalid.
+   * @param builder the builder to which the scalar value is to be appended
+   * @param escapeSequence the escape sequence that was parsed to produce the scalar value
+   * @param scalarValue the value to be appended
+   * @param startIndex the index of the first character representing the scalar value
+   * @param endIndex the index of the last character representing the scalar value
+   */
+  void appendScalarValue(StringBuffer builder, String escapeSequence, int scalarValue, int startIndex, int endIndex) {
+    if (scalarValue < 0 || scalarValue > Character.MAX_CODE_POINT || (scalarValue >= 0xD800 && scalarValue <= 0xDFFF)) {
+      reportError3(ParserErrorCode.INVALID_CODE_POINT, [escapeSequence]);
+      return;
+    }
+    if (scalarValue < Character.MAX_VALUE) {
+      builder.addCharCode(scalarValue as int);
+    } else {
+      builder.add(Character.toChars(scalarValue));
+    }
+  }
+  /**
+   * Compute the content of a string with the given literal representation.
+   * @param lexeme the literal representation of the string
+   * @return the actual value of the string
+   */
+  String computeStringValue(String lexeme) {
+    if (lexeme.startsWith("r\"\"\"") || lexeme.startsWith("r'''")) {
+      if (lexeme.length > 4) {
+        return lexeme.substring(4, lexeme.length - 3);
+      }
+    } else if (lexeme.startsWith("r\"") || lexeme.startsWith("r'")) {
+      if (lexeme.length > 2) {
+        return lexeme.substring(2, lexeme.length - 1);
+      }
+    }
+    int start = 0;
+    if (lexeme.startsWith("\"\"\"") || lexeme.startsWith("'''")) {
+      start += 3;
+    } else if (lexeme.startsWith("\"") || lexeme.startsWith("'")) {
+      start += 1;
+    }
+    int end = lexeme.length;
+    if (end > 3 && (lexeme.endsWith("\"\"\"") || lexeme.endsWith("'''"))) {
+      end -= 3;
+    } else if (end > 1 && (lexeme.endsWith("\"") || lexeme.endsWith("'"))) {
+      end -= 1;
+    }
+    StringBuffer builder = new StringBuffer();
+    int index = start;
+    while (index < end) {
+      index = translateCharacter(builder, lexeme, index);
+    }
+    return builder.toString();
+  }
+  /**
+   * Create a synthetic identifier.
+   * @return the synthetic identifier that was created
+   */
+  SimpleIdentifier createSyntheticIdentifier() => new SimpleIdentifier(createSyntheticToken(TokenType.IDENTIFIER));
+  /**
+   * Create a synthetic string literal.
+   * @return the synthetic string literal that was created
+   */
+  SimpleStringLiteral createSyntheticStringLiteral() => new SimpleStringLiteral(createSyntheticToken(TokenType.STRING), "");
+  /**
+   * Create a synthetic token with the given type.
+   * @return the synthetic token that was created
+   */
+  Token createSyntheticToken(TokenType type) => new StringToken(type, "", _currentToken.offset);
+  /**
+   * Check that the given expression is assignable and report an error if it isn't.
+   * <pre>
+   * assignableExpression ::=
+   * primary (arguments* assignableSelector)+
+   * | 'super' assignableSelector
+   * | identifier
+   * assignableSelector ::=
+   * '[' expression ']'
+   * | '.' identifier
+   * </pre>
+   * @param expression the expression being checked
+   */
+  void ensureAssignable(Expression expression) {
+    if (expression != null && !expression.isAssignable()) {
+      reportError3(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, []);
+    }
+  }
+  /**
+   * If the current token is a keyword matching the given string, return it after advancing to the
+   * next token. Otherwise report an error and return the current token without advancing.
+   * @param keyword the keyword that is expected
+   * @return the token that matched the given type
+   */
+  Token expect(Keyword keyword) {
+    if (matches(keyword)) {
+      return andAdvance;
+    }
+    reportError3(ParserErrorCode.EXPECTED_TOKEN, [keyword.syntax]);
+    return _currentToken;
+  }
+  /**
+   * If the current token has the expected type, return it after advancing to the next token.
+   * Otherwise report an error and return the current token without advancing.
+   * @param type the type of token that is expected
+   * @return the token that matched the given type
+   */
+  Token expect2(TokenType type) {
+    if (matches5(type)) {
+      return andAdvance;
+    }
+    if (type == TokenType.SEMICOLON) {
+      reportError4(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [type.lexeme]);
+    } else {
+      reportError3(ParserErrorCode.EXPECTED_TOKEN, [type.lexeme]);
+    }
+    return _currentToken;
+  }
+  /**
+   * Advance to the next token in the token stream, making it the new current token.
+   * @return the token that was current before this method was invoked
+   */
+  Token get andAdvance {
+    Token token = _currentToken;
+    advance();
+    return token;
+  }
+  /**
+   * Return {@code true} if the current token is the first token of a return type that is followed
+   * by an identifier, possibly followed by a list of type parameters, followed by a
+   * left-parenthesis. This is used by parseTypeAlias to determine whether or not to parse a return
+   * type.
+   * @return {@code true} if we can successfully parse the rest of a type alias if we first parse a
+   * return type.
+   */
+  bool hasReturnTypeInTypeAlias() {
+    Token next = skipReturnType(_currentToken);
+    if (next == null) {
+      return false;
+    }
+    return matchesIdentifier2(next);
+  }
+  /**
+   * Return {@code true} if the current token appears to be the beginning of a function declaration.
+   * @return {@code true} if the current token appears to be the beginning of a function declaration
+   */
+  bool isFunctionDeclaration() {
+    if (matches(Keyword.VOID)) {
+      return true;
+    }
+    Token afterReturnType = skipTypeName(_currentToken);
+    if (afterReturnType == null) {
+      afterReturnType = _currentToken;
+    }
+    Token afterIdentifier = skipSimpleIdentifier(afterReturnType);
+    if (afterIdentifier == null) {
+      afterIdentifier = skipSimpleIdentifier(_currentToken);
+    }
+    if (afterIdentifier == null) {
+      return false;
+    }
+    return isFunctionExpression(afterIdentifier);
+  }
+  /**
+   * Return {@code true} if the given token appears to be the beginning of a function expression.
+   * @param startToken the token that might be the start of a function expression
+   * @return {@code true} if the given token appears to be the beginning of a function expression
+   */
+  bool isFunctionExpression(Token startToken) {
+    Token afterParameters = skipFormalParameterList(startToken);
+    if (afterParameters == null) {
+      return false;
+    }
+    return matchesAny(afterParameters, [TokenType.OPEN_CURLY_BRACKET, TokenType.FUNCTION]);
+  }
+  /**
+   * Return {@code true} if the given character is a valid hexadecimal digit.
+   * @param character the character being tested
+   * @return {@code true} if the character is a valid hexadecimal digit
+   */
+  bool isHexDigit(int character) => (0x30 <= character && character <= 0x39) || (0x41 <= character && character <= 0x46) || (0x61 <= character && character <= 0x66);
+  /**
+   * Return {@code true} if the current token is the first token in an initialized variable
+   * declaration rather than an expression. This method assumes that we have already skipped past
+   * any metadata that might be associated with the declaration.
+   * <pre>
+   * initializedVariableDeclaration ::=
+   * declaredIdentifier ('=' expression)? (',' initializedIdentifier)
+   * declaredIdentifier ::=
+   * metadata finalConstVarOrType identifier
+   * finalConstVarOrType ::=
+   * 'final' type?
+   * | 'const' type?
+   * | 'var'
+   * | type
+   * type ::=
+   * qualified typeArguments?
+   * initializedIdentifier ::=
+   * identifier ('=' expression)?
+   * </pre>
+   * @return {@code true} if the current token is the first token in an initialized variable
+   * declaration
+   */
+  bool isInitializedVariableDeclaration() {
+    if (matches(Keyword.FINAL) || matches(Keyword.CONST) || matches(Keyword.VAR)) {
+      return true;
+    }
+    Token token = skipTypeName(_currentToken);
+    if (token == null) {
+      return false;
+    }
+    token = skipSimpleIdentifier(token);
+    if (token == null) {
+      return false;
+    }
+    TokenType type17 = token.type;
+    return type17 == TokenType.EQ || type17 == TokenType.COMMA || type17 == TokenType.SEMICOLON || matches3(token, Keyword.IN);
+  }
+  /**
+   * Return {@code true} if the current token appears to be the beginning of a switch member.
+   * @return {@code true} if the current token appears to be the beginning of a switch member
+   */
+  bool isSwitchMember() {
+    Token token = _currentToken;
+    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;
+    }
+    return false;
+  }
+  /**
+   * Compare the given tokens to find the token that appears first in the source being parsed. That
+   * is, return the left-most of all of the tokens. The arguments are allowed to be {@code null}.
+   * Return the token with the smallest offset, or {@code null} if there are no arguments or if all
+   * of the arguments are {@code null}.
+   * @param tokens the tokens being compared
+   * @return the token with the smallest offset
+   */
+  Token lexicallyFirst(List<Token> tokens) {
+    Token first = null;
+    int firstOffset = 2147483647;
+    for (Token token in tokens) {
+      if (token != null) {
+        int offset3 = token.offset;
+        if (offset3 < firstOffset) {
+          first = token;
+        }
+      }
+    }
+    return first;
+  }
+  /**
+   * Return {@code true} if the current token matches the given keyword.
+   * @param keyword the keyword that can optionally appear in the current location
+   * @return {@code true} if the current token matches the given keyword
+   */
+  bool matches(Keyword keyword) => matches3(_currentToken, keyword);
+  /**
+   * Return {@code true} if the current token matches the given identifier.
+   * @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;
+  /**
+   * 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;
+  /**
+   * 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;
+  /**
+   * 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
+   * particular, if we are attempting to match a '>' and the next token is either a '>>' or '>>>',
+   * the token stream will be re-written and {@code true} will be returned.
+   * @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) {
+    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) {
+          int offset5 = _currentToken.offset;
+          Token first = new Token(TokenType.GT, offset5);
+          Token second = new Token(TokenType.EQ, offset5 + 1);
+          second.setNext(_currentToken.next);
+          first.setNext(second);
+          _currentToken.previous.setNext(first);
+          _currentToken = first;
+          return true;
+        } else if (currentType == TokenType.GT_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);
+          third.setNext(_currentToken.next);
+          second.setNext(third);
+          first.setNext(second);
+          _currentToken.previous.setNext(first);
+          _currentToken = first;
+          return true;
+        }
+      }
+      return false;
+    }
+    return true;
+  }
+  /**
+   * Return {@code true} if the given token has any one of the given types.
+   * @param token the token being tested
+   * @param types the types of token that are being tested for
+   * @return {@code true} if the given token has any of the given types
+   */
+  bool matchesAny(Token token, List<TokenType> types) {
+    TokenType actualType = token.type;
+    for (TokenType type in types) {
+      if (actualType == type) {
+        return true;
+      }
+    }
+    return false;
+  }
+  /**
+   * Return {@code true} if the current token is a valid identifier. Valid identifiers include
+   * built-in identifiers (pseudo-keywords).
+   * @return {@code true} if the current token is a valid identifier
+   */
+  bool matchesIdentifier() => matchesIdentifier2(_currentToken);
+  /**
+   * Return {@code true} if the given token is a valid identifier. Valid identifiers include
+   * 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());
+  /**
+   * 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
+   * @return {@code true} if the current token has the given type
+   */
+  bool optional(TokenType type) {
+    if (matches5(type)) {
+      advance();
+      return true;
+    }
+    return false;
+  }
+  /**
+   * Parse an additive expression.
+   * <pre>
+   * additiveExpression ::=
+   * multiplicativeExpression (additiveOperator multiplicativeExpression)
+   * | 'super' (additiveOperator multiplicativeExpression)+
+   * </pre>
+   * @return the additive expression that was parsed
+   */
+  Expression parseAdditiveExpression() {
+    Expression expression;
+    if (matches(Keyword.SUPER) && _currentToken.next.type.isAdditiveOperator()) {
+      expression = new SuperExpression(andAdvance);
+    } else {
+      expression = parseMultiplicativeExpression();
+    }
+    while (_currentToken.type.isAdditiveOperator()) {
+      Token operator = andAdvance;
+      expression = new BinaryExpression(expression, operator, parseMultiplicativeExpression());
+    }
+    return expression;
+  }
+  /**
+   * Parse an annotation.
+   * <pre>
+   * annotation ::=
+   * '@' qualified (‘.’ identifier)? arguments?
+   * </pre>
+   * @return the annotation that was parsed
+   */
+  Annotation parseAnnotation() {
+    Token atSign = expect2(TokenType.AT);
+    Identifier name = parsePrefixedIdentifier();
+    Token period = null;
+    SimpleIdentifier constructorName = null;
+    if (matches5(TokenType.PERIOD)) {
+      period = andAdvance;
+      constructorName = parseSimpleIdentifier();
+    }
+    ArgumentList arguments = null;
+    if (matches5(TokenType.OPEN_PAREN)) {
+      arguments = parseArgumentList();
+    }
+    return new Annotation(atSign, name, period, constructorName, arguments);
+  }
+  /**
+   * Parse an argument.
+   * <pre>
+   * argument ::=
+   * namedArgument
+   * | expression
+   * namedArgument ::=
+   * label expression
+   * </pre>
+   * @return the argument that was parsed
+   */
+  Expression parseArgument() {
+    if (matchesIdentifier() && matches4(peek(), TokenType.COLON)) {
+      SimpleIdentifier label = new SimpleIdentifier(andAdvance);
+      Label name = new Label(label, andAdvance);
+      return new NamedExpression(name, parseExpression2());
+    } else {
+      return parseExpression2();
+    }
+  }
+  /**
+   * Parse an argument definition test.
+   * <pre>
+   * argumentDefinitionTest ::=
+   * '?' identifier
+   * </pre>
+   * @return the argument definition test that was parsed
+   */
+  ArgumentDefinitionTest parseArgumentDefinitionTest() {
+    Token question = expect2(TokenType.QUESTION);
+    SimpleIdentifier identifier = parseSimpleIdentifier();
+    return new ArgumentDefinitionTest(question, identifier);
+  }
+  /**
+   * Parse a list of arguments.
+   * <pre>
+   * arguments ::=
+   * '(' argumentList? ')'
+   * argumentList ::=
+   * namedArgument (',' namedArgument)
+   * | expressionList (',' namedArgument)
+   * </pre>
+   * @return the argument list that was parsed
+   */
+  ArgumentList parseArgumentList() {
+    Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
+    List<Expression> arguments = new List<Expression>();
+    if (matches5(TokenType.CLOSE_PAREN)) {
+      return new ArgumentList(leftParenthesis, arguments, andAdvance);
+    }
+    Expression argument = parseArgument();
+    arguments.add(argument);
+    bool foundNamedArgument = argument is NamedExpression;
+    bool generatedError = false;
+    while (optional(TokenType.COMMA)) {
+      argument = parseArgument();
+      arguments.add(argument);
+      if (foundNamedArgument) {
+        if (!generatedError && argument is! NamedExpression) {
+          reportError3(ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT, []);
+          generatedError = true;
+        }
+      } else if (argument is NamedExpression) {
+        foundNamedArgument = true;
+      }
+    }
+    Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
+    return new ArgumentList(leftParenthesis, arguments, rightParenthesis);
+  }
+  /**
+   * Parse an assert statement.
+   * <pre>
+   * assertStatement ::=
+   * 'assert' '(' conditionalExpression ')' ';'
+   * </pre>
+   * @return the assert statement
+   */
+  AssertStatement parseAssertStatement() {
+    Token keyword = expect(Keyword.ASSERT);
+    Token leftParen = expect2(TokenType.OPEN_PAREN);
+    Expression expression = parseConditionalExpression();
+    Token rightParen = expect2(TokenType.CLOSE_PAREN);
+    Token semicolon = expect2(TokenType.SEMICOLON);
+    return new AssertStatement(keyword, leftParen, expression, rightParen, semicolon);
+  }
+  /**
+   * Parse an assignable expression.
+   * <pre>
+   * assignableExpression ::=
+   * primary (arguments* assignableSelector)+
+   * | 'super' assignableSelector
+   * | identifier
+   * </pre>
+   * @param primaryAllowed {@code true} if the expression is allowed to be a primary without any
+   * assignable selector
+   * @return the assignable expression that was parsed
+   */
+  Expression parseAssignableExpression(bool primaryAllowed) {
+    if (matches(Keyword.SUPER)) {
+      return parseAssignableSelector(new SuperExpression(andAdvance), false);
+    }
+    Expression expression = parsePrimaryExpression();
+    bool isOptional = primaryAllowed || expression is SimpleIdentifier;
+    while (true) {
+      while (matches5(TokenType.OPEN_PAREN)) {
+        ArgumentList argumentList = parseArgumentList();
+        if (expression is SimpleIdentifier) {
+          expression = new MethodInvocation(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);
+        } else if (expression is PropertyAccess) {
+          PropertyAccess access = expression as PropertyAccess;
+          expression = new MethodInvocation(access.target, access.operator, access.propertyName, argumentList);
+        } else {
+          expression = new FunctionExpressionInvocation(expression, argumentList);
+        }
+        if (!primaryAllowed) {
+          isOptional = false;
+        }
+      }
+      Expression selectorExpression = parseAssignableSelector(expression, isOptional || (expression is PrefixedIdentifier));
+      if (selectorExpression == expression) {
+        if (!isOptional && (expression is PrefixedIdentifier)) {
+          PrefixedIdentifier identifier = expression as PrefixedIdentifier;
+          expression = new PropertyAccess(identifier.prefix, identifier.period, identifier.identifier);
+        }
+        return expression;
+      }
+      expression = selectorExpression;
+      isOptional = true;
+    }
+  }
+  /**
+   * Parse an assignable selector.
+   * <pre>
+   * assignableSelector ::=
+   * '[' expression ']'
+   * | '.' identifier
+   * </pre>
+   * @param prefix the expression preceding the selector
+   * @param optional {@code true} if the selector is optional
+   * @return the assignable selector that was parsed
+   */
+  Expression parseAssignableSelector(Expression prefix, bool optional) {
+    if (matches5(TokenType.OPEN_SQUARE_BRACKET)) {
+      Token leftBracket = andAdvance;
+      Expression index = parseExpression2();
+      Token rightBracket = expect2(TokenType.CLOSE_SQUARE_BRACKET);
+      return new IndexExpression.con1(prefix, leftBracket, index, rightBracket);
+    } else if (matches5(TokenType.PERIOD)) {
+      Token period = andAdvance;
+      return new PropertyAccess(prefix, period, parseSimpleIdentifier());
+    } else {
+      if (!optional) {
+        reportError3(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []);
+      }
+      return prefix;
+    }
+  }
+  /**
+   * Parse a bitwise and expression.
+   * <pre>
+   * bitwiseAndExpression ::=
+   * equalityExpression ('&' equalityExpression)
+   * | 'super' ('&' equalityExpression)+
+   * </pre>
+   * @return the bitwise and expression that was parsed
+   */
+  Expression parseBitwiseAndExpression() {
+    Expression expression;
+    if (matches(Keyword.SUPER) && matches4(peek(), TokenType.AMPERSAND)) {
+      expression = new SuperExpression(andAdvance);
+    } else {
+      expression = parseEqualityExpression();
+    }
+    while (matches5(TokenType.AMPERSAND)) {
+      Token operator = andAdvance;
+      expression = new BinaryExpression(expression, operator, parseEqualityExpression());
+    }
+    return expression;
+  }
+  /**
+   * Parse a bitwise or expression.
+   * <pre>
+   * bitwiseOrExpression ::=
+   * bitwiseXorExpression ('|' bitwiseXorExpression)
+   * | 'super' ('|' bitwiseXorExpression)+
+   * </pre>
+   * @return the bitwise or expression that was parsed
+   */
+  Expression parseBitwiseOrExpression() {
+    Expression expression;
+    if (matches(Keyword.SUPER) && matches4(peek(), TokenType.BAR)) {
+      expression = new SuperExpression(andAdvance);
+    } else {
+      expression = parseBitwiseXorExpression();
+    }
+    while (matches5(TokenType.BAR)) {
+      Token operator = andAdvance;
+      expression = new BinaryExpression(expression, operator, parseBitwiseXorExpression());
+    }
+    return expression;
+  }
+  /**
+   * Parse a bitwise exclusive-or expression.
+   * <pre>
+   * bitwiseXorExpression ::=
+   * bitwiseAndExpression ('^' bitwiseAndExpression)
+   * | 'super' ('^' bitwiseAndExpression)+
+   * </pre>
+   * @return the bitwise exclusive-or expression that was parsed
+   */
+  Expression parseBitwiseXorExpression() {
+    Expression expression;
+    if (matches(Keyword.SUPER) && matches4(peek(), TokenType.CARET)) {
+      expression = new SuperExpression(andAdvance);
+    } else {
+      expression = parseBitwiseAndExpression();
+    }
+    while (matches5(TokenType.CARET)) {
+      Token operator = andAdvance;
+      expression = new BinaryExpression(expression, operator, parseBitwiseAndExpression());
+    }
+    return expression;
+  }
+  /**
+   * Parse a block.
+   * <pre>
+   * block ::=
+   * '{' statements '}'
+   * </pre>
+   * @return the block that was parsed
+   */
+  Block parseBlock() {
+    Token leftBracket = expect2(TokenType.OPEN_CURLY_BRACKET);
+    List<Statement> statements = new List<Statement>();
+    Token statementStart = _currentToken;
+    while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET)) {
+      Statement statement = parseStatement2();
+      if (statement != null) {
+        statements.add(statement);
+      }
+      if (_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);
+  }
+  /**
+   * Parse a break statement.
+   * <pre>
+   * breakStatement ::=
+   * 'break' identifier? ';'
+   * </pre>
+   * @return the break statement that was parsed
+   */
+  Statement parseBreakStatement() {
+    Token breakKeyword = expect(Keyword.BREAK);
+    SimpleIdentifier label = null;
+    if (matchesIdentifier()) {
+      label = parseSimpleIdentifier();
+    }
+    if (!_inLoop && !_inSwitch && label == null) {
+      reportError4(ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, breakKeyword, []);
+    }
+    Token semicolon = expect2(TokenType.SEMICOLON);
+    return new BreakStatement(breakKeyword, label, semicolon);
+  }
+  /**
+   * Parse a cascade section.
+   * <pre>
+   * cascadeSection ::=
+   * '..' cascadeSelector arguments* (assignableSelector arguments*)* cascadeAssignment?
+   * cascadeSelector ::=
+   * '[' expression ']'
+   * | identifier
+   * cascadeAssignment ::=
+   * assignmentOperator expressionWithoutCascade
+   * </pre>
+   * @return the expression representing the cascaded method invocation
+   */
+  Expression parseCascadeSection() {
+    Token period = expect2(TokenType.PERIOD_PERIOD);
+    Expression expression = null;
+    SimpleIdentifier functionName = null;
+    if (matchesIdentifier()) {
+      functionName = parseSimpleIdentifier();
+    } else if (_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);
+      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 (functionName != null) {
+          expression = new MethodInvocation(expression, period, functionName, parseArgumentList());
+          period = null;
+          functionName = null;
+        } else if (expression == null) {
+          return null;
+        } else {
+          expression = new FunctionExpressionInvocation(expression, parseArgumentList());
+        }
+      }
+    } else if (functionName != null) {
+      expression = new PropertyAccess(expression, period, functionName);
+      period = null;
+    }
+    bool progress = true;
+    while (progress) {
+      progress = false;
+      Expression selector = parseAssignableSelector(expression, true);
+      if (selector != expression) {
+        expression = selector;
+        progress = true;
+        while (_currentToken.type == TokenType.OPEN_PAREN) {
+          expression = new FunctionExpressionInvocation(expression, parseArgumentList());
+        }
+      }
+    }
+    if (_currentToken.type.isAssignmentOperator()) {
+      Token operator = andAdvance;
+      ensureAssignable(expression);
+      expression = new AssignmentExpression(expression, operator, parseExpression2());
+    }
+    return expression;
+  }
+  /**
+   * Parse a class declaration.
+   * <pre>
+   * classDeclaration ::=
+   * metadata 'abstract'? 'class' name typeParameterList? (extendsClause withClause?)? implementsClause? '{' classMembers '}'
+   * </pre>
+   * @param commentAndMetadata the metadata to be associated with the member
+   * @param abstractKeyword the token for the keyword 'abstract', or {@code null} if the keyword was
+   * not given
+   * @return the class declaration that was parsed
+   */
+  ClassDeclaration parseClassDeclaration(CommentAndMetadata commentAndMetadata, Token abstractKeyword) {
+    Token keyword = expect(Keyword.CLASS);
+    SimpleIdentifier name = parseSimpleIdentifier2(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
+    String className = name.name;
+    TypeParameterList typeParameters = null;
+    if (matches5(TokenType.LT)) {
+      typeParameters = parseTypeParameterList();
+    }
+    ExtendsClause extendsClause = null;
+    WithClause withClause = null;
+    ImplementsClause implementsClause = null;
+    bool foundClause = true;
+    while (foundClause) {
+      if (matches(Keyword.EXTENDS)) {
+        if (extendsClause == null) {
+          extendsClause = parseExtendsClause();
+          if (withClause != null) {
+            reportError4(ParserErrorCode.WITH_BEFORE_EXTENDS, withClause.withKeyword, []);
+          } else if (implementsClause != null) {
+            reportError4(ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS, implementsClause.keyword, []);
+          }
+        } else {
+          reportError4(ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES, extendsClause.keyword, []);
+          parseExtendsClause();
+        }
+      } else if (matches(Keyword.WITH)) {
+        if (withClause == null) {
+          withClause = parseWithClause();
+          if (implementsClause != null) {
+            reportError4(ParserErrorCode.IMPLEMENTS_BEFORE_WITH, implementsClause.keyword, []);
+          }
+        } else {
+          reportError4(ParserErrorCode.MULTIPLE_WITH_CLAUSES, withClause.withKeyword, []);
+          parseWithClause();
+        }
+      } else if (matches(Keyword.IMPLEMENTS)) {
+        if (implementsClause == null) {
+          implementsClause = parseImplementsClause();
+        } else {
+          reportError4(ParserErrorCode.MULTIPLE_IMPLEMENTS_CLAUSES, implementsClause.keyword, []);
+          parseImplementsClause();
+        }
+      } else {
+        foundClause = false;
+      }
+    }
+    if (withClause != null && extendsClause == null) {
+      reportError4(ParserErrorCode.WITH_WITHOUT_EXTENDS, withClause.withKeyword, []);
+    }
+    Token leftBracket = null;
+    List<ClassMember> members = null;
+    Token rightBracket = null;
+    if (matches5(TokenType.OPEN_CURLY_BRACKET)) {
+      leftBracket = expect2(TokenType.OPEN_CURLY_BRACKET);
+      members = parseClassMembers(className);
+      rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET);
+    } else {
+      leftBracket = createSyntheticToken(TokenType.OPEN_CURLY_BRACKET);
+      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);
+  }
+  /**
+   * Parse a class member.
+   * <pre>
+   * classMemberDefinition ::=
+   * declaration ';'
+   * | methodSignature functionBody
+   * </pre>
+   * @param className the name of the class containing the member being parsed
+   * @return the class member that was parsed
+   */
+  ClassMember parseClassMember(String className) {
+    CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
+    Modifiers modifiers = parseModifiers();
+    if (matches(Keyword.VOID)) {
+      TypeName returnType = parseReturnType();
+      if (matches(Keyword.GET) && matchesIdentifier2(peek())) {
+        validateModifiersForGetterOrSetterOrMethod(modifiers);
+        return parseGetter(commentAndMetadata, modifiers.externalKeyword, modifiers.staticKeyword, returnType);
+      } else if (matches(Keyword.SET) && matchesIdentifier2(peek())) {
+        validateModifiersForGetterOrSetterOrMethod(modifiers);
+        return parseSetter(commentAndMetadata, modifiers.externalKeyword, modifiers.staticKeyword, returnType);
+      } else if (matches(Keyword.OPERATOR) && peek().isOperator()) {
+        validateModifiersForOperator(modifiers);
+        return parseOperator(commentAndMetadata, modifiers.externalKeyword, returnType);
+      } else if (matchesIdentifier() && matchesAny(peek(), [TokenType.OPEN_PAREN, TokenType.OPEN_CURLY_BRACKET, TokenType.FUNCTION])) {
+        validateModifiersForGetterOrSetterOrMethod(modifiers);
+        return parseMethodDeclaration(commentAndMetadata, modifiers.externalKeyword, modifiers.staticKeyword, returnType);
+      } else {
+        if (matchesIdentifier()) {
+          if (matchesAny(peek(), [TokenType.EQ, TokenType.COMMA, TokenType.SEMICOLON])) {
+            reportError(ParserErrorCode.VOID_VARIABLE, returnType, []);
+            return parseInitializedIdentifierList(commentAndMetadata, modifiers.staticKeyword, validateModifiersForField(modifiers), returnType);
+          }
+        }
+        return null;
+      }
+    } else if (matches(Keyword.GET) && matchesIdentifier2(peek())) {
+      validateModifiersForGetterOrSetterOrMethod(modifiers);
+      return parseGetter(commentAndMetadata, modifiers.externalKeyword, modifiers.staticKeyword, null);
+    } else if (matches(Keyword.SET) && matchesIdentifier2(peek())) {
+      validateModifiersForGetterOrSetterOrMethod(modifiers);
+      return parseSetter(commentAndMetadata, modifiers.externalKeyword, modifiers.staticKeyword, null);
+    } else if (matches(Keyword.OPERATOR) && peek().isOperator()) {
+      validateModifiersForOperator(modifiers);
+      return parseOperator(commentAndMetadata, modifiers.externalKeyword, null);
+    } else if (!matchesIdentifier()) {
+      return null;
+    } else if (matches4(peek(), TokenType.PERIOD) && matchesIdentifier2(peek2(2)) && matches4(peek2(3), TokenType.OPEN_PAREN)) {
+      return parseConstructor(commentAndMetadata, modifiers.externalKeyword, validateModifiersForConstructor(modifiers), modifiers.factoryKeyword, parseSimpleIdentifier(), andAdvance, parseSimpleIdentifier(), parseFormalParameterList());
+    } else if (matches4(peek(), TokenType.OPEN_PAREN)) {
+      SimpleIdentifier methodName = parseSimpleIdentifier();
+      FormalParameterList parameters = parseFormalParameterList();
+      if (matches5(TokenType.COLON) || modifiers.factoryKeyword != null || methodName.name == className) {
+        return parseConstructor(commentAndMetadata, modifiers.externalKeyword, validateModifiersForConstructor(modifiers), modifiers.factoryKeyword, methodName, null, null, parameters);
+      }
+      validateModifiersForGetterOrSetterOrMethod(modifiers);
+      validateFormalParameterList(parameters);
+      return parseMethodDeclaration2(commentAndMetadata, modifiers.externalKeyword, modifiers.staticKeyword, null, methodName, parameters);
+    } else if (matchesAny(peek(), [TokenType.EQ, TokenType.COMMA, TokenType.SEMICOLON])) {
+      return parseInitializedIdentifierList(commentAndMetadata, modifiers.staticKeyword, validateModifiersForField(modifiers), null);
+    }
+    TypeName type = parseTypeName();
+    if (matches(Keyword.GET) && matchesIdentifier2(peek())) {
+      validateModifiersForGetterOrSetterOrMethod(modifiers);
+      return parseGetter(commentAndMetadata, modifiers.externalKeyword, modifiers.staticKeyword, type);
+    } else if (matches(Keyword.SET) && matchesIdentifier2(peek())) {
+      validateModifiersForGetterOrSetterOrMethod(modifiers);
+      return parseSetter(commentAndMetadata, modifiers.externalKeyword, modifiers.staticKeyword, type);
+    } else if (matches(Keyword.OPERATOR) && peek().isOperator()) {
+      validateModifiersForOperator(modifiers);
+      return parseOperator(commentAndMetadata, modifiers.externalKeyword, type);
+    } else if (!matchesIdentifier()) {
+    } else if (matches4(peek(), TokenType.OPEN_PAREN)) {
+      validateModifiersForGetterOrSetterOrMethod(modifiers);
+      return parseMethodDeclaration(commentAndMetadata, modifiers.externalKeyword, modifiers.staticKeyword, type);
+    }
+    return parseInitializedIdentifierList(commentAndMetadata, modifiers.staticKeyword, validateModifiersForField(modifiers), type);
+  }
+  /**
+   * Parse a list of class members.
+   * <pre>
+   * classMembers ::=
+   * (metadata memberDefinition)
+   * </pre>
+   * @return the list of class members that were parsed
+   */
+  List<ClassMember> parseClassMembers(String className) {
+    List<ClassMember> members = new List<ClassMember>();
+    Token memberStart = _currentToken;
+    while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET) && !matches(Keyword.CLASS) && !matches(Keyword.TYPEDEF)) {
+      if (matches5(TokenType.SEMICOLON)) {
+        reportError4(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
+        advance();
+      } else {
+        ClassMember member = parseClassMember(className);
+        if (member != null) {
+          members.add(member);
+        }
+      }
+      if (_currentToken == memberStart) {
+        reportError4(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
+        advance();
+      }
+      memberStart = _currentToken;
+    }
+    return members;
+  }
+  /**
+   * Parse a class type alias.
+   * <pre>
+   * classTypeAlias ::=
+   * identifier typeParameters? '=' 'abstract'? mixinApplication
+   * mixinApplication ::=
+   * type withClause implementsClause? ';'
+   * </pre>
+   * @param commentAndMetadata the metadata to be associated with the member
+   * @param keyword the token representing the 'typedef' keyword
+   * @return the class type alias that was parsed
+   */
+  ClassTypeAlias parseClassTypeAlias(CommentAndMetadata commentAndMetadata, Token keyword) {
+    SimpleIdentifier name = parseSimpleIdentifier();
+    TypeParameterList typeParameters = null;
+    if (matches5(TokenType.LT)) {
+      typeParameters = parseTypeParameterList();
+    }
+    Token equals = expect2(TokenType.EQ);
+    Token abstractKeyword = null;
+    if (matches(Keyword.ABSTRACT)) {
+      abstractKeyword = andAdvance;
+    }
+    TypeName superclass = parseTypeName();
+    WithClause withClause = parseWithClause();
+    ImplementsClause implementsClause = null;
+    if (matches(Keyword.IMPLEMENTS)) {
+      implementsClause = parseImplementsClause();
+    }
+    Token semicolon = expect2(TokenType.SEMICOLON);
+    return new ClassTypeAlias(commentAndMetadata.comment, commentAndMetadata.metadata, keyword, name, typeParameters, equals, abstractKeyword, superclass, withClause, implementsClause, semicolon);
+  }
+  /**
+   * Parse a list of combinators in a directive.
+   * <pre>
+   * combinator ::=
+   * 'show' identifier (',' identifier)
+   * | 'hide' identifier (',' identifier)
+   * </pre>
+   * @return the combinators that were parsed
+   */
+  List<Combinator> parseCombinators() {
+    List<Combinator> combinators = new List<Combinator>();
+    while (matches2(Parser._SHOW) || matches2(Parser._HIDE)) {
+      Token keyword = expect2(TokenType.IDENTIFIER);
+      if (keyword.lexeme == Parser._SHOW) {
+        List<SimpleIdentifier> shownNames = parseIdentifierList();
+        combinators.add(new ShowCombinator(keyword, shownNames));
+      } else {
+        List<SimpleIdentifier> hiddenNames = parseIdentifierList();
+        combinators.add(new HideCombinator(keyword, hiddenNames));
+      }
+    }
+    return combinators;
+  }
+  /**
+   * Parse the documentation comment and metadata preceeding a declaration. This method allows any
+   * number of documentation comments to occur before, after or between the metadata, but only
+   * returns the last (right-most) documentation comment that is found.
+   * <pre>
+   * metadata ::=
+   * annotation
+   * </pre>
+   * @return the documentation comment and metadata that were parsed
+   */
+  CommentAndMetadata parseCommentAndMetadata() {
+    Comment comment = parseDocumentationComment();
+    List<Annotation> metadata = new List<Annotation>();
+    while (matches5(TokenType.AT)) {
+      metadata.add(parseAnnotation());
+      Comment optionalComment = parseDocumentationComment();
+      if (optionalComment != null) {
+        comment = optionalComment;
+      }
+    }
+    return new CommentAndMetadata(comment, metadata);
+  }
+  /**
+   * Parse a comment reference from the source between square brackets.
+   * <pre>
+   * commentReference ::=
+   * 'new'? prefixedIdentifier
+   * </pre>
+   * @param referenceSource the source occurring between the square brackets within a documentation
+   * comment
+   * @param sourceOffset the offset of the first character of the reference source
+   * @return the comment reference that was parsed
+   */
+  CommentReference parseCommentReference(String referenceSource, int sourceOffset) {
+    if (referenceSource.length == 0) {
+      return null;
+    }
+    try {
+      List<bool> errorFound = [false];
+      AnalysisErrorListener listener = new AnalysisErrorListener_1(errorFound);
+      StringScanner scanner = new StringScanner(null, referenceSource, listener);
+      scanner.setSourceStart(1, 1, sourceOffset);
+      Token firstToken = scanner.tokenize();
+      if (!errorFound[0]) {
+        Token newKeyword = null;
+        if (matches3(firstToken, Keyword.NEW)) {
+          newKeyword = firstToken;
+          firstToken = firstToken.next;
+        }
+        if (matchesIdentifier2(firstToken)) {
+          Token secondToken = firstToken.next;
+          Token thirdToken = secondToken.next;
+          Token nextToken;
+          Identifier identifier;
+          if (matches4(secondToken, TokenType.PERIOD) && matchesIdentifier2(thirdToken)) {
+            identifier = new PrefixedIdentifier(new SimpleIdentifier(firstToken), secondToken, new SimpleIdentifier(thirdToken));
+            nextToken = thirdToken.next;
+          } else {
+            identifier = new SimpleIdentifier(firstToken);
+            nextToken = firstToken.next;
+          }
+          if (nextToken.type != TokenType.EOF) {
+          }
+          return new CommentReference(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) {
+    }
+    return null;
+  }
+  /**
+   * Parse all of the comment references occurring in the given array of documentation comments.
+   * <pre>
+   * commentReference ::=
+   * '[' 'new'? qualified ']' libraryReference?
+   * libraryReference ::=
+   * '(' stringLiteral ')'
+   * </pre>
+   * @param tokens the comment tokens representing the documentation comments to be parsed
+   * @return the comment references that were parsed
+   */
+  List<CommentReference> parseCommentReferences(List<Token> tokens) {
+    List<CommentReference> references = new List<CommentReference>();
+    for (Token token in tokens) {
+      String comment = token.lexeme;
+      int leftIndex = comment.indexOf('[');
+      while (leftIndex >= 0) {
+        int rightIndex = comment.indexOf(']', leftIndex);
+        if (rightIndex >= 0) {
+          int firstChar = comment.charCodeAt(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);
+            }
+          }
+        } else {
+          rightIndex = leftIndex + 1;
+        }
+        leftIndex = comment.indexOf('[', rightIndex);
+      }
+    }
+    return references;
+  }
+  /**
+   * Parse a compilation unit.
+   * <p>
+   * Specified:
+   * <pre>
+   * compilationUnit ::=
+   * scriptTag? directive* topLevelDeclaration
+   * </pre>
+   * Actual:
+   * <pre>
+   * compilationUnit ::=
+   * scriptTag? topLevelElement
+   * topLevelElement ::=
+   * directive
+   * | topLevelDeclaration
+   * </pre>
+   * @return the compilation unit that was parsed
+   */
+  CompilationUnit parseCompilationUnit2() {
+    Token firstToken = _currentToken.precedingComments;
+    if (firstToken == null) {
+      firstToken = _currentToken;
+    }
+    ScriptTag scriptTag = null;
+    if (matches5(TokenType.SCRIPT_TAG)) {
+      scriptTag = new ScriptTag(andAdvance);
+    }
+    bool libraryDirectiveFound = false;
+    bool partOfDirectiveFound = false;
+    bool partDirectiveFound = false;
+    bool directiveFoundAfterDeclaration = false;
+    List<Directive> directives = new List<Directive>();
+    List<CompilationUnitMember> declarations = new List<CompilationUnitMember>();
+    Token memberStart = _currentToken;
+    while (!matches5(TokenType.EOF)) {
+      CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
+      if (matches(Keyword.IMPORT) || matches(Keyword.EXPORT) || matches(Keyword.LIBRARY) || matches(Keyword.PART)) {
+        Directive directive = parseDirective(commentAndMetadata);
+        if (declarations.length > 0 && !directiveFoundAfterDeclaration) {
+          reportError3(ParserErrorCode.DIRECTIVE_AFTER_DECLARATION, []);
+          directiveFoundAfterDeclaration = true;
+        }
+        if (directive is LibraryDirective) {
+          if (libraryDirectiveFound) {
+            reportError3(ParserErrorCode.MULTIPLE_LIBRARY_DIRECTIVES, []);
+          } else {
+            if (directives.length > 0) {
+              reportError3(ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST, []);
+            }
+            libraryDirectiveFound = true;
+          }
+        } else if (directive is PartDirective) {
+          partDirectiveFound = true;
+        } else if (partDirectiveFound) {
+          if (directive is ExportDirective) {
+            reportError3(ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, []);
+          } else if (directive is ImportDirective) {
+            reportError3(ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, []);
+          }
+        }
+        if (directive is PartOfDirective) {
+          if (partOfDirectiveFound) {
+            reportError3(ParserErrorCode.MULTIPLE_PART_OF_DIRECTIVES, []);
+          } else {
+            for (Directive preceedingDirective in directives) {
+              reportError4(ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART, preceedingDirective.keyword, []);
+            }
+            partOfDirectiveFound = true;
+          }
+        } else {
+          if (partOfDirectiveFound) {
+            reportError4(ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART, directive.keyword, []);
+          }
+        }
+        directives.add(directive);
+      } else if (matches5(TokenType.SEMICOLON)) {
+        reportError4(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
+        advance();
+      } else {
+        CompilationUnitMember member = parseCompilationUnitMember(commentAndMetadata);
+        if (member != null) {
+          declarations.add(member);
+        }
+      }
+      if (_currentToken == memberStart) {
+        reportError4(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
+        advance();
+      }
+      memberStart = _currentToken;
+    }
+    return new CompilationUnit(firstToken, scriptTag, directives, declarations, _currentToken);
+  }
+  /**
+   * Parse a compilation unit member.
+   * <pre>
+   * compilationUnitMember ::=
+   * classDefinition
+   * | functionTypeAlias
+   * | external functionSignature
+   * | external getterSignature
+   * | external setterSignature
+   * | functionSignature functionBody
+   * | returnType? getOrSet identifier formalParameterList functionBody
+   * | (final | const) type? staticFinalDeclarationList ';'
+   * | variableDeclaration ';'
+   * </pre>
+   * @param commentAndMetadata the metadata to be associated with the member
+   * @return the compilation unit member that was parsed
+   */
+  CompilationUnitMember parseCompilationUnitMember(CommentAndMetadata commentAndMetadata) {
+    Modifiers modifiers = parseModifiers();
+    if (matches(Keyword.CLASS)) {
+      return parseClassDeclaration(commentAndMetadata, validateModifiersForClass(modifiers));
+    } else if (matches(Keyword.TYPEDEF)) {
+      validateModifiersForTypedef(modifiers);
+      return parseTypeAlias(commentAndMetadata);
+    }
+    if (matches(Keyword.VOID)) {
+      TypeName returnType = parseReturnType();
+      if ((matches(Keyword.GET) || matches(Keyword.SET)) && matchesIdentifier2(peek())) {
+        validateModifiersForTopLevelFunction(modifiers);
+        return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, null, false);
+      } else if (matches(Keyword.OPERATOR) && peek().isOperator()) {
+        return null;
+      } else if (matchesIdentifier() && matchesAny(peek(), [TokenType.OPEN_PAREN, TokenType.OPEN_CURLY_BRACKET, TokenType.FUNCTION])) {
+        validateModifiersForTopLevelFunction(modifiers);
+        return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, null, false);
+      } else {
+        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 null;
+      }
+    } else if ((matches(Keyword.GET) || matches(Keyword.SET)) && matchesIdentifier2(peek())) {
+      validateModifiersForTopLevelFunction(modifiers);
+      return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, null, false);
+    } else if (matches(Keyword.OPERATOR) && peek().isOperator()) {
+      return null;
+    } else if (!matchesIdentifier()) {
+      return null;
+    } else if (matches4(peek(), TokenType.OPEN_PAREN)) {
+      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));
+    }
+    TypeName returnType = parseReturnType();
+    if (matches(Keyword.GET) || matches(Keyword.SET)) {
+      validateModifiersForTopLevelFunction(modifiers);
+      return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, returnType, false);
+    } else if (!matchesIdentifier()) {
+      return null;
+    }
+    if (matchesAny(peek(), [TokenType.OPEN_PAREN, TokenType.FUNCTION, TokenType.OPEN_CURLY_BRACKET])) {
+      validateModifiersForTopLevelFunction(modifiers);
+      return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyword, returnType, false);
+    }
+    return new TopLevelVariableDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, parseVariableDeclarationList2(validateModifiersForTopLevelVariable(modifiers), returnType), expect2(TokenType.SEMICOLON));
+  }
+  /**
+   * Parse a conditional expression.
+   * <pre>
+   * conditionalExpression ::=
+   * logicalOrExpression ('?' expressionWithoutCascade ':' expressionWithoutCascade)?
+   * </pre>
+   * @return the conditional expression that was parsed
+   */
+  Expression parseConditionalExpression() {
+    Expression condition = parseLogicalOrExpression();
+    if (!matches5(TokenType.QUESTION)) {
+      return condition;
+    }
+    Token question = andAdvance;
+    Expression thenExpression = parseExpressionWithoutCascade();
+    Token colon = expect2(TokenType.COLON);
+    Expression elseExpression = parseExpressionWithoutCascade();
+    return new ConditionalExpression(condition, question, thenExpression, colon, elseExpression);
+  }
+  /**
+   * Parse a const expression.
+   * <pre>
+   * constExpression ::=
+   * instanceCreationExpression
+   * | listLiteral
+   * | mapLiteral
+   * </pre>
+   * @return the const expression that was parsed
+   */
+  Expression parseConstExpression() {
+    Token keyword = expect(Keyword.CONST);
+    if (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.INDEX)) {
+      return parseListLiteral(keyword, null);
+    } else if (matches5(TokenType.OPEN_CURLY_BRACKET)) {
+      return parseMapLiteral(keyword, null);
+    } else if (matches5(TokenType.LT)) {
+      return parseListOrMapLiteral(keyword);
+    }
+    return parseInstanceCreationExpression(keyword);
+  }
+  ConstructorDeclaration parseConstructor(CommentAndMetadata commentAndMetadata, Token externalKeyword, Token constKeyword, Token factoryKeyword, SimpleIdentifier returnType, Token period, SimpleIdentifier name, FormalParameterList parameters) {
+    bool bodyAllowed = externalKeyword == null;
+    Token separator = null;
+    List<ConstructorInitializer> initializers = null;
+    if (matches5(TokenType.COLON)) {
+      separator = andAdvance;
+      initializers = new List<ConstructorInitializer>();
+      do {
+        if (matches(Keyword.THIS)) {
+          if (matches4(peek(), TokenType.OPEN_PAREN)) {
+            bodyAllowed = false;
+            initializers.add(parseRedirectingConstructorInvocation());
+          } else if (matches4(peek(), TokenType.PERIOD) && matches4(peek2(3), TokenType.OPEN_PAREN)) {
+            bodyAllowed = false;
+            initializers.add(parseRedirectingConstructorInvocation());
+          } else {
+            initializers.add(parseConstructorFieldInitializer());
+          }
+        } else if (matches(Keyword.SUPER)) {
+          initializers.add(parseSuperConstructorInvocation());
+        } else {
+          initializers.add(parseConstructorFieldInitializer());
+        }
+      } while (optional(TokenType.COMMA));
+    }
+    ConstructorName redirectedConstructor = null;
+    FunctionBody body;
+    if (matches5(TokenType.EQ)) {
+      separator = andAdvance;
+      redirectedConstructor = parseConstructorName();
+      body = new EmptyFunctionBody(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);
+  }
+  /**
+   * Parse a field initializer within a constructor.
+   * <pre>
+   * fieldInitializer:
+   * ('this' '.')? identifier '=' conditionalExpression cascadeSection
+   * </pre>
+   * @return the field initializer that was parsed
+   */
+  ConstructorFieldInitializer parseConstructorFieldInitializer() {
+    Token keyword = null;
+    Token period = null;
+    if (matches(Keyword.THIS)) {
+      keyword = andAdvance;
+      period = expect2(TokenType.PERIOD);
+    }
+    SimpleIdentifier fieldName = parseSimpleIdentifier();
+    Token equals = expect2(TokenType.EQ);
+    Expression expression = parseConditionalExpression();
+    TokenType tokenType = _currentToken.type;
+    if (tokenType == TokenType.PERIOD_PERIOD) {
+      List<Expression> cascadeSections = new List<Expression>();
+      while (tokenType == TokenType.PERIOD_PERIOD) {
+        Expression section = parseCascadeSection();
+        if (section != null) {
+          cascadeSections.add(section);
+        }
+        tokenType = _currentToken.type;
+      }
+      expression = new CascadeExpression(expression, cascadeSections);
+    }
+    return new ConstructorFieldInitializer(keyword, period, fieldName, equals, expression);
+  }
+  /**
+   * Parse the name of a constructor.
+   * <pre>
+   * constructorName:
+   * type ('.' identifier)?
+   * </pre>
+   * @return the constructor name that was parsed
+   */
+  ConstructorName parseConstructorName() {
+    TypeName type = parseTypeName();
+    Token period = null;
+    SimpleIdentifier name = null;
+    if (matches5(TokenType.PERIOD)) {
+      period = andAdvance;
+      name = parseSimpleIdentifier();
+    }
+    return new ConstructorName(type, period, name);
+  }
+  /**
+   * Parse a continue statement.
+   * <pre>
+   * continueStatement ::=
+   * 'continue' identifier? ';'
+   * </pre>
+   * @return the continue statement that was parsed
+   */
+  Statement parseContinueStatement() {
+    Token continueKeyword = expect(Keyword.CONTINUE);
+    if (!_inLoop && !_inSwitch) {
+      reportError4(ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, continueKeyword, []);
+    }
+    SimpleIdentifier label = null;
+    if (matchesIdentifier()) {
+      label = parseSimpleIdentifier();
+    }
+    if (_inSwitch && !_inLoop && label == null) {
+      reportError4(ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE, continueKeyword, []);
+    }
+    Token semicolon = expect2(TokenType.SEMICOLON);
+    return new ContinueStatement(continueKeyword, label, semicolon);
+  }
+  /**
+   * Parse a directive.
+   * <pre>
+   * directive ::=
+   * exportDirective
+   * | libraryDirective
+   * | importDirective
+   * | partDirective
+   * </pre>
+   * @param commentAndMetadata the metadata to be associated with the directive
+   * @return the directive that was parsed
+   */
+  Directive parseDirective(CommentAndMetadata commentAndMetadata) {
+    if (matches(Keyword.IMPORT)) {
+      return parseImportDirective(commentAndMetadata);
+    } else if (matches(Keyword.EXPORT)) {
+      return parseExportDirective(commentAndMetadata);
+    } else if (matches(Keyword.LIBRARY)) {
+      return parseLibraryDirective(commentAndMetadata);
+    } else if (matches(Keyword.PART)) {
+      return parsePartDirective(commentAndMetadata);
+    } else {
+      return null;
+    }
+  }
+  /**
+   * Parse a documentation comment.
+   * <pre>
+   * documentationComment ::=
+   * multiLineComment?
+   * | singleLineComment
+   * </pre>
+   * @return the documentation comment that was parsed, or {@code null} if there was no comment
+   */
+  Comment parseDocumentationComment() {
+    List<Token> commentTokens = new List<Token>();
+    Token commentToken = _currentToken.precedingComments;
+    while (commentToken != null) {
+      if (commentToken.type == TokenType.SINGLE_LINE_COMMENT) {
+        if (commentToken.lexeme.startsWith("///")) {
+          if (commentTokens.length == 1 && commentTokens[0].lexeme.startsWith("/**")) {
+            commentTokens.clear();
+          }
+          commentTokens.add(commentToken);
+        }
+      } else {
+        if (commentToken.lexeme.startsWith("/**")) {
+          commentTokens.clear();
+          commentTokens.add(commentToken);
+        }
+      }
+      commentToken = commentToken.next;
+    }
+    if (commentTokens.isEmpty) {
+      return null;
+    }
+    List<Token> tokens = new List.from(commentTokens);
+    List<CommentReference> references = parseCommentReferences(tokens);
+    return Comment.createDocumentationComment2(tokens, references);
+  }
+  /**
+   * Parse a do statement.
+   * <pre>
+   * doStatement ::=
+   * 'do' statement 'while' '(' expression ')' ';'
+   * </pre>
+   * @return the do statement that was parsed
+   */
+  Statement parseDoStatement() {
+    bool wasInLoop = _inLoop;
+    _inLoop = true;
+    try {
+      Token doKeyword = expect(Keyword.DO);
+      Statement body = parseStatement2();
+      Token whileKeyword = expect(Keyword.WHILE);
+      Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
+      Expression condition = parseExpression2();
+      Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
+      Token semicolon = expect2(TokenType.SEMICOLON);
+      return new DoStatement(doKeyword, body, whileKeyword, leftParenthesis, condition, rightParenthesis, semicolon);
+    } finally {
+      _inLoop = wasInLoop;
+    }
+  }
+  /**
+   * Parse an empty statement.
+   * <pre>
+   * emptyStatement ::=
+   * ';'
+   * </pre>
+   * @return the empty statement that was parsed
+   */
+  Statement parseEmptyStatement() => new EmptyStatement(andAdvance);
+  /**
+   * Parse an equality expression.
+   * <pre>
+   * equalityExpression ::=
+   * relationalExpression (equalityOperator relationalExpression)?
+   * | 'super' equalityOperator relationalExpression
+   * </pre>
+   * @return the equality expression that was parsed
+   */
+  Expression parseEqualityExpression() {
+    Expression expression;
+    if (matches(Keyword.SUPER) && _currentToken.next.type.isEqualityOperator()) {
+      expression = new SuperExpression(andAdvance);
+    } else {
+      expression = parseRelationalExpression();
+    }
+    while (_currentToken.type.isEqualityOperator()) {
+      Token operator = andAdvance;
+      expression = new BinaryExpression(expression, operator, parseRelationalExpression());
+    }
+    return expression;
+  }
+  /**
+   * Parse an export directive.
+   * <pre>
+   * exportDirective ::=
+   * metadata 'export' stringLiteral combinator*';'
+   * </pre>
+   * @param commentAndMetadata the metadata to be associated with the directive
+   * @return the export directive that was parsed
+   */
+  ExportDirective parseExportDirective(CommentAndMetadata commentAndMetadata) {
+    Token exportKeyword = expect(Keyword.EXPORT);
+    StringLiteral libraryUri = parseStringLiteral();
+    List<Combinator> combinators = parseCombinators();
+    Token semicolon = expect2(TokenType.SEMICOLON);
+    return new ExportDirective(commentAndMetadata.comment, commentAndMetadata.metadata, exportKeyword, libraryUri, combinators, semicolon);
+  }
+  /**
+   * Parse an expression that does not contain any cascades.
+   * <pre>
+   * expression ::=
+   * assignableExpression assignmentOperator expression
+   * | conditionalExpression cascadeSection
+   * | throwExpression
+   * </pre>
+   * @return the expression that was parsed
+   */
+  Expression parseExpression2() {
+    if (matches(Keyword.THROW)) {
+      return parseThrowExpression();
+    }
+    Expression expression = parseConditionalExpression();
+    TokenType tokenType = _currentToken.type;
+    if (tokenType == TokenType.PERIOD_PERIOD) {
+      List<Expression> cascadeSections = new List<Expression>();
+      while (tokenType == TokenType.PERIOD_PERIOD) {
+        Expression section = parseCascadeSection();
+        if (section != null) {
+          cascadeSections.add(section);
+        }
+        tokenType = _currentToken.type;
+      }
+      return new CascadeExpression(expression, cascadeSections);
+    } else if (tokenType.isAssignmentOperator()) {
+      Token operator = andAdvance;
+      ensureAssignable(expression);
+      return new AssignmentExpression(expression, operator, parseExpression2());
+    }
+    return expression;
+  }
+  /**
+   * Parse a list of expressions.
+   * <pre>
+   * expressionList ::=
+   * expression (',' expression)
+   * </pre>
+   * @return the expression that was parsed
+   */
+  List<Expression> parseExpressionList() {
+    List<Expression> expressions = new List<Expression>();
+    expressions.add(parseExpression2());
+    while (optional(TokenType.COMMA)) {
+      expressions.add(parseExpression2());
+    }
+    return expressions;
+  }
+  /**
+   * Parse an expression that does not contain any cascades.
+   * <pre>
+   * expressionWithoutCascade ::=
+   * assignableExpression assignmentOperator expressionWithoutCascade
+   * | conditionalExpression
+   * | throwExpressionWithoutCascade
+   * </pre>
+   * @return the expression that was parsed
+   */
+  Expression parseExpressionWithoutCascade() {
+    if (matches(Keyword.THROW)) {
+      return parseThrowExpressionWithoutCascade();
+    }
+    Expression expression = parseConditionalExpression();
+    if (_currentToken.type.isAssignmentOperator()) {
+      Token operator = andAdvance;
+      ensureAssignable(expression);
+      expression = new AssignmentExpression(expression, operator, parseExpressionWithoutCascade());
+    }
+    return expression;
+  }
+  /**
+   * Parse a class extends clause.
+   * <pre>
+   * classExtendsClause ::=
+   * 'extends' type
+   * </pre>
+   * @return the class extends clause that was parsed
+   */
+  ExtendsClause parseExtendsClause() {
+    Token keyword = expect(Keyword.EXTENDS);
+    TypeName superclass = parseTypeName();
+    return new ExtendsClause(keyword, superclass);
+  }
+  /**
+   * Parse the 'final', 'const', 'var' or type preceding a variable declaration.
+   * <pre>
+   * finalConstVarOrType ::=
+   * | 'final' type?
+   * | 'const' type?
+   * | 'var'
+   * | type
+   * </pre>
+   * @param optional {@code true} if the keyword and type are optional
+   * @return the 'final', 'const', 'var' or type that was parsed
+   */
+  FinalConstVarOrType parseFinalConstVarOrType(bool optional) {
+    Token keyword = null;
+    TypeName type = null;
+    if (matches(Keyword.FINAL) || matches(Keyword.CONST)) {
+      keyword = andAdvance;
+      if (matchesIdentifier2(peek()) || matches4(peek(), TokenType.LT) || matches3(peek(), Keyword.THIS)) {
+        type = parseTypeName();
+      }
+    } else if (matches(Keyword.VAR)) {
+      keyword = andAdvance;
+    } else {
+      if (matchesIdentifier2(peek()) || matches4(peek(), TokenType.LT) || matches3(peek(), Keyword.THIS) || (matches4(peek(), TokenType.PERIOD) && matchesIdentifier2(peek2(2)) && (matchesIdentifier2(peek2(3)) || matches4(peek2(3), TokenType.LT) || matches3(peek2(3), Keyword.THIS)))) {
+        type = parseReturnType();
+      } else if (!optional) {
+        reportError3(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, []);
+      }
+    }
+    return new FinalConstVarOrType(keyword, type);
+  }
+  /**
+   * Parse a formal parameter. At most one of {@code isOptional} and {@code isNamed} can be{@code true}.
+   * <pre>
+   * defaultFormalParameter ::=
+   * normalFormalParameter ('=' expression)?
+   * defaultNamedParameter ::=
+   * normalFormalParameter (':' expression)?
+   * </pre>
+   * @param kind the kind of parameter being expected based on the presence or absence of group
+   * delimiters
+   * @return the formal parameter that was parsed
+   */
+  FormalParameter parseFormalParameter(ParameterKind kind) {
+    NormalFormalParameter parameter = parseNormalFormalParameter();
+    if (matches5(TokenType.EQ)) {
+      Token seperator = andAdvance;
+      Expression defaultValue = parseExpression2();
+      if (kind == ParameterKind.NAMED) {
+        reportError4(ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER, seperator, []);
+      } else if (kind == ParameterKind.REQUIRED) {
+        reportError(ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP, parameter, []);
+      }
+      return new DefaultFormalParameter(parameter, kind, seperator, defaultValue);
+    } else if (matches5(TokenType.COLON)) {
+      Token seperator = andAdvance;
+      Expression defaultValue = parseExpression2();
+      if (kind == ParameterKind.POSITIONAL) {
+        reportError4(ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER, seperator, []);
+      } else if (kind == ParameterKind.REQUIRED) {
+        reportError(ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP, parameter, []);
+      }
+      return new DefaultFormalParameter(parameter, kind, seperator, defaultValue);
+    } else if (kind != ParameterKind.REQUIRED) {
+      return new DefaultFormalParameter(parameter, kind, null, null);
+    }
+    return parameter;
+  }
+  /**
+   * Parse a list of formal parameters.
+   * <pre>
+   * formalParameterList ::=
+   * '(' ')'
+   * | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
+   * | '(' optionalFormalParameters ')'
+   * normalFormalParameters ::=
+   * normalFormalParameter (',' normalFormalParameter)
+   * optionalFormalParameters ::=
+   * optionalPositionalFormalParameters
+   * | namedFormalParameters
+   * optionalPositionalFormalParameters ::=
+   * '[' defaultFormalParameter (',' defaultFormalParameter)* ']'
+   * namedFormalParameters ::=
+   * '{' defaultNamedParameter (',' defaultNamedParameter)* '}'
+   * </pre>
+   * @return the formal parameters that were parsed
+   */
+  FormalParameterList parseFormalParameterList() {
+    Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
+    if (matches5(TokenType.CLOSE_PAREN)) {
+      return new FormalParameterList(leftParenthesis, null, null, null, andAdvance);
+    }
+    List<FormalParameter> parameters = new List<FormalParameter>();
+    List<FormalParameter> normalParameters = new List<FormalParameter>();
+    List<FormalParameter> positionalParameters = new List<FormalParameter>();
+    List<FormalParameter> namedParameters = new List<FormalParameter>();
+    List<FormalParameter> currentParameters = normalParameters;
+    Token leftSquareBracket = null;
+    Token rightSquareBracket = null;
+    Token leftCurlyBracket = null;
+    Token rightCurlyBracket = null;
+    ParameterKind kind = ParameterKind.REQUIRED;
+    bool firstParameter = true;
+    bool reportedMuliplePositionalGroups = false;
+    bool reportedMulipleNamedGroups = false;
+    bool reportedMixedGroups = false;
+    Token initialToken = null;
+    do {
+      if (firstParameter) {
+        firstParameter = false;
+      } else if (!optional(TokenType.COMMA)) {
+        if ((leftParenthesis as BeginToken).endToken != null) {
+          reportError3(ParserErrorCode.EXPECTED_TOKEN, [TokenType.COMMA.lexeme]);
+        } else {
+          break;
+        }
+      }
+      initialToken = _currentToken;
+      if (matches5(TokenType.OPEN_SQUARE_BRACKET)) {
+        if (leftSquareBracket != null && !reportedMuliplePositionalGroups) {
+          reportError3(ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS, []);
+          reportedMuliplePositionalGroups = true;
+        }
+        if (leftCurlyBracket != null && !reportedMixedGroups) {
+          reportError3(ParserErrorCode.MIXED_PARAMETER_GROUPS, []);
+          reportedMixedGroups = true;
+        }
+        leftSquareBracket = andAdvance;
+        currentParameters = positionalParameters;
+        kind = ParameterKind.POSITIONAL;
+      } else if (matches5(TokenType.OPEN_CURLY_BRACKET)) {
+        if (leftCurlyBracket != null && !reportedMulipleNamedGroups) {
+          reportError3(ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS, []);
+          reportedMulipleNamedGroups = true;
+        }
+        if (leftSquareBracket != null && !reportedMixedGroups) {
+          reportError3(ParserErrorCode.MIXED_PARAMETER_GROUPS, []);
+          reportedMixedGroups = true;
+        }
+        leftCurlyBracket = andAdvance;
+        currentParameters = namedParameters;
+        kind = ParameterKind.NAMED;
+      }
+      FormalParameter parameter = parseFormalParameter(kind);
+      parameters.add(parameter);
+      currentParameters.add(parameter);
+      if (matches5(TokenType.CLOSE_SQUARE_BRACKET)) {
+        rightSquareBracket = andAdvance;
+        currentParameters = normalParameters;
+        if (leftSquareBracket == null) {
+        }
+        kind = ParameterKind.REQUIRED;
+      } else if (matches5(TokenType.CLOSE_CURLY_BRACKET)) {
+        rightCurlyBracket = andAdvance;
+        currentParameters = normalParameters;
+        if (leftCurlyBracket == null) {
+        }
+        kind = ParameterKind.REQUIRED;
+      }
+    } while (!matches5(TokenType.CLOSE_PAREN) && initialToken != _currentToken);
+    Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
+    if (leftSquareBracket != null && rightSquareBracket == null) {
+    }
+    if (leftCurlyBracket != null && rightCurlyBracket == null) {
+    }
+    if (leftSquareBracket == null) {
+      leftSquareBracket = leftCurlyBracket;
+    }
+    if (rightSquareBracket == null) {
+      rightSquareBracket = rightCurlyBracket;
+    }
+    return new FormalParameterList(leftParenthesis, parameters, leftSquareBracket, rightSquareBracket, rightParenthesis);
+  }
+  /**
+   * Parse a for statement.
+   * <pre>
+   * forStatement ::=
+   * 'for' '(' forLoopParts ')' statement
+   * forLoopParts ::=
+   * forInitializerStatement expression? ';' expressionList?
+   * | declaredIdentifier 'in' expression
+   * | identifier 'in' expression
+   * forInitializerStatement ::=
+   * variableDeclarationList ';'
+   * | expression? ';'
+   * </pre>
+   * @return the for statement that was parsed
+   */
+  Statement parseForStatement() {
+    bool wasInLoop = _inLoop;
+    _inLoop = true;
+    try {
+      Token forKeyword = expect(Keyword.FOR);
+      Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
+      VariableDeclarationList variableList = null;
+      Expression initialization = null;
+      if (!matches5(TokenType.SEMICOLON)) {
+        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);
+        } else if (isInitializedVariableDeclaration()) {
+          variableList = parseVariableDeclarationList();
+        } else {
+          initialization = parseExpression2();
+        }
+        if (matches(Keyword.IN)) {
+          SimpleFormalParameter loopParameter = null;
+          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()]);
+            }
+            VariableDeclaration variable = variables5[0];
+            if (variable.initializer != null) {
+              reportError3(ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH, []);
+            }
+            loopParameter = new SimpleFormalParameter(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);
+        }
+      }
+      Token leftSeparator = expect2(TokenType.SEMICOLON);
+      Expression condition = null;
+      if (!matches5(TokenType.SEMICOLON)) {
+        condition = parseExpression2();
+      }
+      Token rightSeparator = expect2(TokenType.SEMICOLON);
+      List<Expression> updaters = null;
+      if (!matches5(TokenType.CLOSE_PAREN)) {
+        updaters = parseExpressionList();
+      }
+      Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
+      Statement body = parseStatement2();
+      return new ForStatement(forKeyword, leftParenthesis, variableList, initialization, leftSeparator, condition, rightSeparator, updaters, rightParenthesis, body);
+    } finally {
+      _inLoop = wasInLoop;
+    }
+  }
+  /**
+   * Parse a function body.
+   * <pre>
+   * functionBody ::=
+   * '=>' expression ';'
+   * | block
+   * functionExpressionBody ::=
+   * '=>' expression
+   * | block
+   * </pre>
+   * @param mayBeEmpty {@code true} if the function body is allowed to be empty
+   * @param inExpression {@code true} if the function body is being parsed as part of an expression
+   * and therefore does not have a terminating semicolon
+   * @return the function body that was parsed
+   */
+  FunctionBody parseFunctionBody(bool mayBeEmpty, bool inExpression) {
+    bool wasInLoop = _inLoop;
+    bool wasInSwitch = _inSwitch;
+    _inLoop = false;
+    _inSwitch = false;
+    try {
+      if (matches5(TokenType.SEMICOLON)) {
+        if (!mayBeEmpty) {
+          reportError3(ParserErrorCode.MISSING_FUNCTION_BODY, []);
+        }
+        return new EmptyFunctionBody(andAdvance);
+      } else if (matches5(TokenType.FUNCTION)) {
+        Token functionDefinition = andAdvance;
+        Expression expression = parseExpression2();
+        Token semicolon = null;
+        if (!inExpression) {
+          semicolon = expect2(TokenType.SEMICOLON);
+        }
+        return new ExpressionFunctionBody(functionDefinition, expression, semicolon);
+      } else if (matches5(TokenType.OPEN_CURLY_BRACKET)) {
+        return new BlockFunctionBody(parseBlock());
+      } else if (matches2("native")) {
+        advance();
+        parseStringLiteral();
+        return new EmptyFunctionBody(andAdvance);
+      } else {
+        reportError3(ParserErrorCode.MISSING_FUNCTION_BODY, []);
+        return new EmptyFunctionBody(createSyntheticToken(TokenType.SEMICOLON));
+      }
+    } finally {
+      _inLoop = wasInLoop;
+      _inSwitch = wasInSwitch;
+    }
+  }
+  /**
+   * Parse a function declaration.
+   * <pre>
+   * functionDeclaration ::=
+   * functionSignature functionBody
+   * | returnType? getOrSet identifier formalParameterList functionBody
+   * </pre>
+   * @param commentAndMetadata the documentation comment and metadata to be associated with the
+   * declaration
+   * @param externalKeyword the 'external' keyword, or {@code null} if the function is not external
+   * @param returnType the return type, or {@code null} if there is no return type
+   * @param isStatement {@code true} if the function declaration is being parsed as a statement
+   * @return the function declaration that was parsed
+   */
+  FunctionDeclaration parseFunctionDeclaration(CommentAndMetadata commentAndMetadata, Token externalKeyword, TypeName returnType, bool isStatement) {
+    Token keyword = null;
+    bool isGetter = false;
+    if (matches(Keyword.GET) && !matches4(peek(), TokenType.OPEN_PAREN)) {
+      keyword = andAdvance;
+      isGetter = true;
+    } else if (matches(Keyword.SET) && !matches4(peek(), TokenType.OPEN_PAREN)) {
+      keyword = andAdvance;
+    }
+    SimpleIdentifier name = parseSimpleIdentifier();
+    FormalParameterList parameters = null;
+    if (!isGetter) {
+      if (matches5(TokenType.OPEN_PAREN)) {
+        parameters = parseFormalParameterList();
+        validateFormalParameterList(parameters);
+      } else {
+        reportError3(ParserErrorCode.MISSING_FUNCTION_PARAMETERS, []);
+      }
+    } else if (matches5(TokenType.OPEN_PAREN)) {
+      reportError3(ParserErrorCode.GETTER_WITH_PARAMETERS, []);
+      parseFormalParameterList();
+    }
+    FunctionBody body = null;
+    if (externalKeyword == null) {
+      body = parseFunctionBody(false, false);
+    }
+    if (!isStatement && matches5(TokenType.SEMICOLON)) {
+      reportError3(ParserErrorCode.UNEXPECTED_TOKEN, [_currentToken.lexeme]);
+      advance();
+    }
+    return new FunctionDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, externalKeyword, returnType, keyword, name, new FunctionExpression(parameters, body));
+  }
+  /**
+   * Parse a function declaration statement.
+   * <pre>
+   * functionDeclarationStatement ::=
+   * functionSignature functionBody
+   * </pre>
+   * @return the function declaration statement that was parsed
+   */
+  Statement parseFunctionDeclarationStatement() => parseFunctionDeclarationStatement2(parseCommentAndMetadata(), parseOptionalReturnType());
+  /**
+   * Parse a function declaration statement.
+   * <pre>
+   * functionDeclarationStatement ::=
+   * functionSignature functionBody
+   * </pre>
+   * @param commentAndMetadata the documentation comment and metadata to be associated with the
+   * declaration
+   * @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));
+  /**
+   * Parse a function expression.
+   * <pre>
+   * functionExpression ::=
+   * (returnType? identifier)? formalParameterList functionExpressionBody
+   * </pre>
+   * @return the function expression that was parsed
+   */
+  FunctionExpression parseFunctionExpression() {
+    FormalParameterList parameters = parseFormalParameterList();
+    validateFormalParameterList(parameters);
+    FunctionBody body = parseFunctionBody(false, true);
+    return new FunctionExpression(parameters, body);
+  }
+  /**
+   * Parse a function type alias.
+   * <pre>
+   * functionTypeAlias ::=
+   * functionPrefix typeParameterList? formalParameterList ';'
+   * functionPrefix ::=
+   * returnType? name
+   * </pre>
+   * @param commentAndMetadata the metadata to be associated with the member
+   * @param keyword the token representing the 'typedef' keyword
+   * @return the function type alias that was parsed
+   */
+  FunctionTypeAlias parseFunctionTypeAlias(CommentAndMetadata commentAndMetadata, Token keyword) {
+    TypeName returnType = null;
+    if (hasReturnTypeInTypeAlias()) {
+      returnType = parseReturnType();
+    }
+    SimpleIdentifier name = parseSimpleIdentifier2(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
+    TypeParameterList typeParameters = null;
+    if (matches5(TokenType.LT)) {
+      typeParameters = parseTypeParameterList();
+    }
+    if (matches5(TokenType.SEMICOLON)) {
+      reportError3(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, []);
+      FormalParameterList parameters = new FormalParameterList(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);
+    } 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);
+  }
+  /**
+   * Parse a getter.
+   * <pre>
+   * getter ::=
+   * getterSignature functionBody?
+   * getterSignature ::=
+   * 'external'? 'static'? returnType? 'get' identifier
+   * </pre>
+   * @param commentAndMetadata the documentation comment and metadata to be associated with the
+   * declaration
+   * @param externalKeyword the 'external' token
+   * @param staticKeyword the static keyword, or {@code null} if the getter is not static
+   * @param the return type that has already been parsed, or {@code null} if there was no return
+   * type
+   * @return the getter that was parsed
+   */
+  MethodDeclaration parseGetter(CommentAndMetadata commentAndMetadata, Token externalKeyword, Token staticKeyword, TypeName returnType) {
+    Token propertyKeyword = expect(Keyword.GET);
+    SimpleIdentifier name = parseSimpleIdentifier();
+    if (matches5(TokenType.OPEN_PAREN) && matches4(peek(), TokenType.CLOSE_PAREN)) {
+      reportError3(ParserErrorCode.GETTER_WITH_PARAMETERS, []);
+      advance();
+      advance();
+    }
+    FunctionBody body = parseFunctionBody(true, false);
+    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);
+  }
+  /**
+   * Parse a list of identifiers.
+   * <pre>
+   * identifierList ::=
+   * identifier (',' identifier)
+   * </pre>
+   * @return the list of identifiers that were parsed
+   */
+  List<SimpleIdentifier> parseIdentifierList() {
+    List<SimpleIdentifier> identifiers = new List<SimpleIdentifier>();
+    identifiers.add(parseSimpleIdentifier());
+    while (matches5(TokenType.COMMA)) {
+      advance();
+      identifiers.add(parseSimpleIdentifier());
+    }
+    return identifiers;
+  }
+  /**
+   * Parse an if statement.
+   * <pre>
+   * ifStatement ::=
+   * 'if' '(' expression ')' statement ('else' statement)?
+   * </pre>
+   * @return the if statement that was parsed
+   */
+  Statement parseIfStatement() {
+    Token ifKeyword = expect(Keyword.IF);
+    Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
+    Expression condition = parseExpression2();
+    Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
+    Statement thenStatement = parseStatement2();
+    Token elseKeyword = null;
+    Statement elseStatement = null;
+    if (matches(Keyword.ELSE)) {
+      elseKeyword = andAdvance;
+      elseStatement = parseStatement2();
+    }
+    return new IfStatement(ifKeyword, leftParenthesis, condition, rightParenthesis, thenStatement, elseKeyword, elseStatement);
+  }
+  /**
+   * Parse an implements clause.
+   * <pre>
+   * implementsClause ::=
+   * 'implements' type (',' type)
+   * </pre>
+   * @return the implements clause that was parsed
+   */
+  ImplementsClause parseImplementsClause() {
+    Token keyword = expect(Keyword.IMPLEMENTS);
+    List<TypeName> interfaces = new List<TypeName>();
+    interfaces.add(parseTypeName());
+    while (optional(TokenType.COMMA)) {
+      interfaces.add(parseTypeName());
+    }
+    return new ImplementsClause(keyword, interfaces);
+  }
+  /**
+   * Parse an import directive.
+   * <pre>
+   * importDirective ::=
+   * metadata 'import' stringLiteral ('as' identifier)? combinator*';'
+   * </pre>
+   * @param commentAndMetadata the metadata to be associated with the directive
+   * @return the import directive that was parsed
+   */
+  ImportDirective parseImportDirective(CommentAndMetadata commentAndMetadata) {
+    Token importKeyword = expect(Keyword.IMPORT);
+    StringLiteral libraryUri = parseStringLiteral();
+    Token asToken = null;
+    SimpleIdentifier prefix = null;
+    if (matches(Keyword.AS)) {
+      asToken = andAdvance;
+      prefix = parseSimpleIdentifier();
+    }
+    List<Combinator> combinators = parseCombinators();
+    Token semicolon = expect2(TokenType.SEMICOLON);
+    return new ImportDirective(commentAndMetadata.comment, commentAndMetadata.metadata, importKeyword, libraryUri, asToken, prefix, combinators, semicolon);
+  }
+  /**
+   * Parse a list of initialized identifiers.
+   * <pre>
+   * ?? ::=
+   * 'static'? ('var' | type) initializedIdentifierList ';'
+   * | 'final' type? initializedIdentifierList ';'
+   * initializedIdentifierList ::=
+   * initializedIdentifier (',' initializedIdentifier)
+   * initializedIdentifier ::=
+   * identifier ('=' expression)?
+   * </pre>
+   * @param commentAndMetadata the documentation comment and metadata to be associated with the
+   * declaration
+   * @param staticKeyword the static keyword, or {@code null} if the getter is not static
+   * @param keyword the token representing the 'final', 'const' or 'var' keyword, or {@code null} if
+   * there is no keyword
+   * @param type the type that has already been parsed, or {@code null} if 'var' was provided
+   * @return the getter that was parsed
+   */
+  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));
+  }
+  /**
+   * Parse an instance creation expression.
+   * <pre>
+   * instanceCreationExpression ::=
+   * ('new' | 'const') type ('.' identifier)? argumentList
+   * </pre>
+   * @param keyword the 'new' or 'const' keyword that introduces the expression
+   * @return the instance creation expression that was parsed
+   */
+  InstanceCreationExpression parseInstanceCreationExpression(Token keyword) {
+    ConstructorName constructorName = parseConstructorName();
+    ArgumentList argumentList = parseArgumentList();
+    return new InstanceCreationExpression(keyword, constructorName, argumentList);
+  }
+  /**
+   * Parse a library directive.
+   * <pre>
+   * libraryDirective ::=
+   * metadata 'library' identifier ';'
+   * </pre>
+   * @param commentAndMetadata the metadata to be associated with the directive
+   * @return the library directive that was parsed
+   */
+  LibraryDirective parseLibraryDirective(CommentAndMetadata commentAndMetadata) {
+    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);
+  }
+  /**
+   * Parse a library identifier.
+   * <pre>
+   * libraryIdentifier ::=
+   * identifier ('.' identifier)
+   * </pre>
+   * @return the library identifier that was parsed
+   */
+  LibraryIdentifier parseLibraryIdentifier() {
+    List<SimpleIdentifier> components = new List<SimpleIdentifier>();
+    components.add(parseSimpleIdentifier());
+    while (matches5(TokenType.PERIOD)) {
+      advance();
+      components.add(parseSimpleIdentifier());
+    }
+    return new LibraryIdentifier(components);
+  }
+  /**
+   * Parse a library name.
+   * <pre>
+   * libraryName ::=
+   * libraryIdentifier
+   * </pre>
+   * @param missingNameError the error code to be used if the library name is missing
+   * @param missingNameToken the token associated with the error produced if the library name is
+   * missing
+   * @return the library name that was parsed
+   */
+  LibraryIdentifier parseLibraryName(ParserErrorCode missingNameError, Token missingNameToken) {
+    if (matchesIdentifier()) {
+      return parseLibraryIdentifier();
+    } else if (matches5(TokenType.STRING)) {
+      StringLiteral string = parseStringLiteral();
+      reportError(ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME, string, []);
+    } else {
+      reportError4(missingNameError, missingNameToken, []);
+    }
+    List<SimpleIdentifier> components = new List<SimpleIdentifier>();
+    components.add(createSyntheticIdentifier());
+    return new LibraryIdentifier(components);
+  }
+  /**
+   * Parse a list literal.
+   * <pre>
+   * listLiteral ::=
+   * 'const'? typeArguments? '[' (expressionList ','?)? ']'
+   * </pre>
+   * @param modifier the 'const' modifier appearing before the literal, or {@code null} if there is
+   * no modifier
+   * @param typeArguments the type arguments appearing before the literal, or {@code null} if there
+   * are no type arguments
+   * @return the list literal that was parsed
+   */
+  ListLiteral parseListLiteral(Token modifier, TypeArgumentList typeArguments) {
+    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;
+      rightBracket.setNext(_currentToken.next);
+      leftBracket.setNext(rightBracket);
+      _currentToken.previous.setNext(leftBracket);
+      _currentToken = _currentToken.next;
+      return new ListLiteral(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);
+    }
+    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);
+      }
+      elements.add(parseExpression2());
+    }
+    Token rightBracket = expect2(TokenType.CLOSE_SQUARE_BRACKET);
+    return new ListLiteral(modifier, typeArguments, leftBracket, elements, rightBracket);
+  }
+  /**
+   * Parse a list or map literal.
+   * <pre>
+   * listOrMapLiteral ::=
+   * listLiteral
+   * | mapLiteral
+   * </pre>
+   * @param modifier the 'const' modifier appearing before the literal, or {@code null} if there is
+   * no modifier
+   * @return the list or map literal that was parsed
+   */
+  TypedLiteral parseListOrMapLiteral(Token modifier) {
+    TypeArgumentList typeArguments = null;
+    if (matches5(TokenType.LT)) {
+      typeArguments = parseTypeArgumentList();
+    }
+    if (matches5(TokenType.OPEN_CURLY_BRACKET)) {
+      return parseMapLiteral(modifier, typeArguments);
+    } else if (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.INDEX)) {
+      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));
+  }
+  /**
+   * Parse a logical and expression.
+   * <pre>
+   * logicalAndExpression ::=
+   * bitwiseOrExpression ('&&' bitwiseOrExpression)
+   * </pre>
+   * @return the logical and expression that was parsed
+   */
+  Expression parseLogicalAndExpression() {
+    Expression expression = parseBitwiseOrExpression();
+    while (matches5(TokenType.AMPERSAND_AMPERSAND)) {
+      Token operator = andAdvance;
+      expression = new BinaryExpression(expression, operator, parseBitwiseOrExpression());
+    }
+    return expression;
+  }
+  /**
+   * Parse a logical or expression.
+   * <pre>
+   * logicalOrExpression ::=
+   * logicalAndExpression ('||' logicalAndExpression)
+   * </pre>
+   * @return the logical or expression that was parsed
+   */
+  Expression parseLogicalOrExpression() {
+    Expression expression = parseLogicalAndExpression();
+    while (matches5(TokenType.BAR_BAR)) {
+      Token operator = andAdvance;
+      expression = new BinaryExpression(expression, operator, parseLogicalAndExpression());
+    }
+    return expression;
+  }
+  /**
+   * Parse a map literal.
+   * <pre>
+   * mapLiteral ::=
+   * 'const'? typeArguments? '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}'
+   * </pre>
+   * @param modifier the 'const' modifier appearing before the literal, or {@code null} if there is
+   * no modifier
+   * @param typeArguments the type arguments that were declared, or {@code null} if there are no
+   * type arguments
+   * @return the map literal that was parsed
+   */
+  MapLiteral parseMapLiteral(Token modifier, TypeArgumentList typeArguments) {
+    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);
+    }
+    entries.add(parseMapLiteralEntry());
+    while (optional(TokenType.COMMA)) {
+      if (matches5(TokenType.CLOSE_CURLY_BRACKET)) {
+        return new MapLiteral(modifier, typeArguments, leftBracket, entries, andAdvance);
+      }
+      entries.add(parseMapLiteralEntry());
+    }
+    Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET);
+    return new MapLiteral(modifier, typeArguments, leftBracket, entries, rightBracket);
+  }
+  /**
+   * Parse a map literal entry.
+   * <pre>
+   * mapLiteralEntry ::=
+   * stringLiteral ':' expression
+   * </pre>
+   * @return the map literal entry that was parsed
+   */
+  MapLiteralEntry parseMapLiteralEntry() {
+    StringLiteral key = parseStringLiteral();
+    Token separator = expect2(TokenType.COLON);
+    Expression value = parseExpression2();
+    return new MapLiteralEntry(key, separator, value);
+  }
+  /**
+   * Parse a method declaration.
+   * <pre>
+   * functionDeclaration ::=
+   * 'external'? 'static'? functionSignature functionBody
+   * | 'external'? functionSignature ';'
+   * </pre>
+   * @param commentAndMetadata the documentation comment and metadata to be associated with the
+   * declaration
+   * @param externalKeyword the 'external' token
+   * @param staticKeyword the static keyword, or {@code null} if the getter is not static
+   * @param returnType the return type of the method
+   * @return the method declaration that was parsed
+   */
+  MethodDeclaration parseMethodDeclaration(CommentAndMetadata commentAndMetadata, Token externalKeyword, Token staticKeyword, TypeName returnType) {
+    SimpleIdentifier methodName = parseSimpleIdentifier();
+    FormalParameterList parameters = parseFormalParameterList();
+    validateFormalParameterList(parameters);
+    return parseMethodDeclaration2(commentAndMetadata, externalKeyword, staticKeyword, returnType, methodName, parameters);
+  }
+  /**
+   * Parse a method declaration.
+   * <pre>
+   * functionDeclaration ::=
+   * ('external' 'static'?)? functionSignature functionBody
+   * | 'external'? functionSignature ';'
+   * </pre>
+   * @param commentAndMetadata the documentation comment and metadata to be associated with the
+   * declaration
+   * @param externalKeyword the 'external' token
+   * @param staticKeyword the static keyword, or {@code null} if the getter is not static
+   * @param returnType the return type of the method
+   * @param name the name of the method
+   * @param parameters the parameters to the method
+   * @return the method declaration that was parsed
+   */
+  MethodDeclaration parseMethodDeclaration2(CommentAndMetadata commentAndMetadata, Token externalKeyword, Token staticKeyword, TypeName returnType, SimpleIdentifier name, FormalParameterList parameters) {
+    FunctionBody body = parseFunctionBody(externalKeyword != null || staticKeyword == null, false);
+    if (externalKeyword != null) {
+      if (body is! EmptyFunctionBody) {
+        reportError(ParserErrorCode.EXTERNAL_METHOD_WITH_BODY, body, []);
+      }
+    } else if (staticKeyword != null) {
+      if (body is EmptyFunctionBody) {
+        reportError(ParserErrorCode.ABSTRACT_STATIC_METHOD, body, []);
+      }
+    }
+    return new MethodDeclaration(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
+   * order but does generate errors for duplicated modifiers. Checks for other problems, such as
+   * having the modifiers appear in the wrong order or specifying both 'const' and 'final', are
+   * reported in one of the methods whose name is prefixed with {@code validateModifiersFor}.
+   * <pre>
+   * modifiers ::=
+   * ('abstract' | 'const' | 'external' | 'factory' | 'final' | 'static' | 'var')
+   * </pre>
+   * @return the modifiers that were parsed
+   */
+  Modifiers parseModifiers() {
+    Modifiers modifiers = new Modifiers();
+    bool progress = true;
+    while (progress) {
+      if (matches(Keyword.ABSTRACT)) {
+        if (modifiers.abstractKeyword != null) {
+          reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          advance();
+        } else {
+          modifiers.abstractKeyword4 = andAdvance;
+        }
+      } else if (matches(Keyword.CONST)) {
+        if (modifiers.constKeyword != null) {
+          reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          advance();
+        } else {
+          modifiers.constKeyword3 = andAdvance;
+        }
+      } else if (matches(Keyword.EXTERNAL)) {
+        if (modifiers.externalKeyword != null) {
+          reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          advance();
+        } else {
+          modifiers.externalKeyword5 = andAdvance;
+        }
+      } else if (matches(Keyword.FACTORY)) {
+        if (modifiers.factoryKeyword != null) {
+          reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          advance();
+        } else {
+          modifiers.factoryKeyword3 = andAdvance;
+        }
+      } else if (matches(Keyword.FINAL)) {
+        if (modifiers.finalKeyword != null) {
+          reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          advance();
+        } else {
+          modifiers.finalKeyword2 = andAdvance;
+        }
+      } else if (matches(Keyword.STATIC)) {
+        if (modifiers.staticKeyword != null) {
+          reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          advance();
+        } else {
+          modifiers.staticKeyword2 = andAdvance;
+        }
+      } else if (matches(Keyword.VAR)) {
+        if (modifiers.varKeyword != null) {
+          reportError3(ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
+          advance();
+        } else {
+          modifiers.varKeyword2 = andAdvance;
+        }
+      } else {
+        progress = false;
+      }
+    }
+    return modifiers;
+  }
+  /**
+   * Parse a multiplicative expression.
+   * <pre>
+   * multiplicativeExpression ::=
+   * unaryExpression (multiplicativeOperator unaryExpression)
+   * | 'super' (multiplicativeOperator unaryExpression)+
+   * </pre>
+   * @return the multiplicative expression that was parsed
+   */
+  Expression parseMultiplicativeExpression() {
+    Expression expression;
+    if (matches(Keyword.SUPER) && _currentToken.next.type.isMultiplicativeOperator()) {
+      expression = new SuperExpression(andAdvance);
+    } else {
+      expression = parseUnaryExpression();
+    }
+    while (_currentToken.type.isMultiplicativeOperator()) {
+      Token operator = andAdvance;
+      expression = new BinaryExpression(expression, operator, parseUnaryExpression());
+    }
+    return expression;
+  }
+  /**
+   * Parse a new expression.
+   * <pre>
+   * newExpression ::=
+   * instanceCreationExpression
+   * </pre>
+   * @return the new expression that was parsed
+   */
+  InstanceCreationExpression parseNewExpression() => parseInstanceCreationExpression(expect(Keyword.NEW));
+  /**
+   * Parse a non-labeled statement.
+   * <pre>
+   * nonLabeledStatement ::=
+   * block
+   * | assertStatement
+   * | breakStatement
+   * | continueStatement
+   * | doStatement
+   * | forStatement
+   * | ifStatement
+   * | returnStatement
+   * | switchStatement
+   * | tryStatement
+   * | whileStatement
+   * | variableDeclarationList ';'
+   * | expressionStatement
+   * | functionSignature functionBody
+   * </pre>
+   * @return the non-labeled statement that was parsed
+   */
+  Statement parseNonLabeledStatement() {
+    CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
+    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));
+        }
+      }
+      return parseBlock();
+    } else if (matches5(TokenType.KEYWORD) && !(_currentToken as KeywordToken).keyword.isPseudoKeyword()) {
+      Keyword keyword29 = (_currentToken as KeywordToken).keyword;
+      if (keyword29 == Keyword.ASSERT) {
+        return parseAssertStatement();
+      } else if (keyword29 == Keyword.BREAK) {
+        return parseBreakStatement();
+      } else if (keyword29 == Keyword.CONTINUE) {
+        return parseContinueStatement();
+      } else if (keyword29 == Keyword.DO) {
+        return parseDoStatement();
+      } else if (keyword29 == Keyword.FOR) {
+        return parseForStatement();
+      } else if (keyword29 == Keyword.IF) {
+        return parseIfStatement();
+      } else if (keyword29 == Keyword.RETURN) {
+        return parseReturnStatement();
+      } else if (keyword29 == Keyword.SWITCH) {
+        return parseSwitchStatement();
+      } else if (keyword29 == Keyword.THROW) {
+        return new ExpressionStatement(parseThrowExpression(), expect2(TokenType.SEMICOLON));
+      } else if (keyword29 == Keyword.TRY) {
+        return parseTryStatement();
+      } else if (keyword29 == Keyword.WHILE) {
+        return parseWhileStatement();
+      } else if (keyword29 == Keyword.VAR || keyword29 == Keyword.FINAL) {
+        return parseVariableDeclarationStatement();
+      } else if (keyword29 == Keyword.VOID) {
+        TypeName returnType = parseReturnType();
+        if (matchesIdentifier() && matchesAny(peek(), [TokenType.OPEN_PAREN, TokenType.OPEN_CURLY_BRACKET, TokenType.FUNCTION])) {
+          return parseFunctionDeclarationStatement2(commentAndMetadata, returnType);
+        } else {
+          if (matchesIdentifier()) {
+            if (matchesAny(peek(), [TokenType.EQ, TokenType.COMMA, TokenType.SEMICOLON])) {
+              reportError(ParserErrorCode.VOID_VARIABLE, returnType, []);
+              return parseVariableDeclarationStatement();
+            }
+          }
+          return null;
+        }
+      } else if (keyword29 == Keyword.CONST) {
+        if (matchesAny(peek(), [TokenType.LT, TokenType.OPEN_CURLY_BRACKET, TokenType.OPEN_SQUARE_BRACKET, TokenType.INDEX])) {
+          return new ExpressionStatement(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 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 {
+        return null;
+      }
+    } else if (matches5(TokenType.SEMICOLON)) {
+      return parseEmptyStatement();
+    } else if (isInitializedVariableDeclaration()) {
+      return parseVariableDeclarationStatement();
+    } else if (isFunctionDeclaration()) {
+      return parseFunctionDeclarationStatement();
+    } else {
+      return new ExpressionStatement(parseExpression2(), expect2(TokenType.SEMICOLON));
+    }
+  }
+  /**
+   * Parse a normal formal parameter.
+   * <pre>
+   * normalFormalParameter ::=
+   * functionSignature
+   * | fieldFormalParameter
+   * | simpleFormalParameter
+   * functionSignature:
+   * metadata returnType? identifier formalParameterList
+   * fieldFormalParameter ::=
+   * metadata finalConstVarOrType? 'this' '.' identifier
+   * simpleFormalParameter ::=
+   * declaredIdentifier
+   * | metadata identifier
+   * </pre>
+   * @return the normal formal parameter that was parsed
+   */
+  NormalFormalParameter parseNormalFormalParameter() {
+    CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
+    FinalConstVarOrType holder = parseFinalConstVarOrType(true);
+    Token thisKeyword = null;
+    Token period = null;
+    if (matches(Keyword.THIS)) {
+      thisKeyword = andAdvance;
+      period = expect2(TokenType.PERIOD);
+    }
+    SimpleIdentifier identifier = parseSimpleIdentifier();
+    if (matches5(TokenType.OPEN_PAREN)) {
+      if (thisKeyword != null) {
+      }
+      FormalParameterList parameters = parseFormalParameterList();
+      return new FunctionTypedFormalParameter(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, []);
+    }
+    if (thisKeyword != null) {
+      return new FieldFormalParameter(commentAndMetadata.comment, commentAndMetadata.metadata, holder.keyword, holder.type, thisKeyword, period, identifier);
+    }
+    return new SimpleFormalParameter(commentAndMetadata.comment, commentAndMetadata.metadata, holder.keyword, holder.type, identifier);
+  }
+  /**
+   * Parse an operator declaration.
+   * <pre>
+   * operatorDeclaration ::=
+   * operatorSignature (';' | functionBody)
+   * operatorSignature ::=
+   * 'external'? returnType? 'operator' operator formalParameterList
+   * </pre>
+   * @param commentAndMetadata the documentation comment and metadata to be associated with the
+   * declaration
+   * @param externalKeyword the 'external' token
+   * @param the return type that has already been parsed, or {@code null} if there was no return
+   * type
+   * @return the operator declaration that was parsed
+   */
+  MethodDeclaration parseOperator(CommentAndMetadata commentAndMetadata, Token externalKeyword, TypeName returnType) {
+    Token operatorKeyword = expect(Keyword.OPERATOR);
+    if (!_currentToken.isUserDefinableOperator()) {
+      reportError3(ParserErrorCode.NON_USER_DEFINABLE_OPERATOR, [_currentToken.lexeme]);
+    }
+    SimpleIdentifier name = new SimpleIdentifier(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);
+  }
+  /**
+   * Parse a return type if one is given, otherwise return {@code null} without advancing.
+   * @return the return type that was parsed
+   */
+  TypeName parseOptionalReturnType() {
+    if (matches(Keyword.VOID)) {
+      return parseReturnType();
+    } else if (matchesIdentifier() && !matches(Keyword.GET) && !matches(Keyword.SET) && !matches(Keyword.OPERATOR) && (matchesIdentifier2(peek()) || matches4(peek(), TokenType.LT))) {
+      return parseReturnType();
+    } else if (matchesIdentifier() && matches4(peek(), TokenType.PERIOD) && matchesIdentifier2(peek2(2)) && (matchesIdentifier2(peek2(3)) || matches4(peek2(3), TokenType.LT))) {
+      return parseReturnType();
+    }
+    return null;
+  }
+  /**
+   * Parse a part or part-of directive.
+   * <pre>
+   * partDirective ::=
+   * metadata 'part' stringLiteral ';'
+   * partOfDirective ::=
+   * metadata 'part' 'of' identifier ';'
+   * </pre>
+   * @param commentAndMetadata the metadata to be associated with the directive
+   * @return the part or part-of directive that was parsed
+   */
+  Directive parsePartDirective(CommentAndMetadata commentAndMetadata) {
+    Token partKeyword = expect(Keyword.PART);
+    if (matches2(Parser._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);
+    }
+    StringLiteral partUri = parseStringLiteral();
+    Token semicolon = expect2(TokenType.SEMICOLON);
+    return new PartDirective(commentAndMetadata.comment, commentAndMetadata.metadata, partKeyword, partUri, semicolon);
+  }
+  /**
+   * Parse a postfix expression.
+   * <pre>
+   * postfixExpression ::=
+   * assignableExpression postfixOperator
+   * | primary selector
+   * selector ::=
+   * assignableSelector
+   * | argumentList
+   * </pre>
+   * @return the postfix expression that was parsed
+   */
+  Expression parsePostfixExpression() {
+    Expression operand = parseAssignableExpression(true);
+    if (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.PERIOD) || matches5(TokenType.OPEN_PAREN)) {
+      do {
+        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);
+          } else {
+            operand = new FunctionExpressionInvocation(operand, argumentList);
+          }
+        } else {
+          operand = parseAssignableSelector(operand, true);
+        }
+      } while (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.PERIOD) || matches5(TokenType.OPEN_PAREN));
+      return operand;
+    }
+    if (!_currentToken.type.isIncrementOperator()) {
+      return operand;
+    }
+    if (operand is FunctionExpressionInvocation) {
+      reportError3(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []);
+    }
+    Token operator = andAdvance;
+    return new PostfixExpression(operand, operator);
+  }
+  /**
+   * Parse a prefixed identifier.
+   * <pre>
+   * prefixedIdentifier ::=
+   * identifier ('.' identifier)?
+   * </pre>
+   * @return the prefixed identifier that was parsed
+   */
+  Identifier parsePrefixedIdentifier() {
+    SimpleIdentifier qualifier = parseSimpleIdentifier();
+    if (!matches5(TokenType.PERIOD)) {
+      return qualifier;
+    }
+    Token period = andAdvance;
+    SimpleIdentifier qualified = parseSimpleIdentifier();
+    return new PrefixedIdentifier(qualifier, period, qualified);
+  }
+  /**
+   * Parse a primary expression.
+   * <pre>
+   * primary ::=
+   * thisExpression
+   * | 'super' assignableSelector
+   * | functionExpression
+   * | literal
+   * | identifier
+   * | newExpression
+   * | constObjectExpression
+   * | '(' expression ')'
+   * | argumentDefinitionTest
+   * literal ::=
+   * nullLiteral
+   * | booleanLiteral
+   * | numericLiteral
+   * | stringLiteral
+   * | mapLiteral
+   * | listLiteral
+   * </pre>
+   * @return the primary expression that was parsed
+   */
+  Expression parsePrimaryExpression() {
+    if (matches(Keyword.THIS)) {
+      return new ThisExpression(andAdvance);
+    } else if (matches(Keyword.SUPER)) {
+      return parseAssignableSelector(new SuperExpression(andAdvance), false);
+    } else if (matches(Keyword.NULL)) {
+      return new NullLiteral(andAdvance);
+    } else if (matches(Keyword.FALSE)) {
+      return new BooleanLiteral(andAdvance, false);
+    } else if (matches(Keyword.TRUE)) {
+      return new BooleanLiteral(andAdvance, true);
+    } else if (matches5(TokenType.DOUBLE)) {
+      Token token = andAdvance;
+      double value = 0.0;
+      try {
+        value = double.parse(token.lexeme);
+      } on NumberFormatException catch (exception) {
+      }
+      return new DoubleLiteral(token, value);
+    } else if (matches5(TokenType.HEXADECIMAL)) {
+      Token token = andAdvance;
+      int value = null;
+      try {
+        value = int.parse(token.lexeme.substring(2), radix: 16);
+      } on NumberFormatException catch (exception) {
+      }
+      return new IntegerLiteral.con1(token, value);
+    } else if (matches5(TokenType.INT)) {
+      Token token = andAdvance;
+      int value = null;
+      try {
+        value = int.parse(token.lexeme);
+      } on NumberFormatException catch (exception) {
+      }
+      return new IntegerLiteral.con1(token, value);
+    } else if (matches5(TokenType.STRING)) {
+      return parseStringLiteral();
+    } else if (matches5(TokenType.OPEN_CURLY_BRACKET)) {
+      return parseMapLiteral(null, null);
+    } else if (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.INDEX)) {
+      return parseListLiteral(null, null);
+    } else if (matchesIdentifier()) {
+      return parsePrefixedIdentifier();
+    } else if (matches(Keyword.NEW)) {
+      return parseNewExpression();
+    } else if (matches(Keyword.CONST)) {
+      return parseConstExpression();
+    } else if (matches5(TokenType.OPEN_PAREN)) {
+      if (isFunctionExpression(_currentToken)) {
+        return parseFunctionExpression();
+      }
+      Token leftParenthesis = andAdvance;
+      Expression expression = parseExpression2();
+      Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
+      return new ParenthesizedExpression(leftParenthesis, expression, rightParenthesis);
+    } else if (matches5(TokenType.LT)) {
+      return parseListOrMapLiteral(null);
+    } else if (matches5(TokenType.QUESTION)) {
+      return parseArgumentDefinitionTest();
+    } else if (matches(Keyword.VOID)) {
+      reportError3(ParserErrorCode.UNEXPECTED_TOKEN, [_currentToken.lexeme]);
+      advance();
+      return parsePrimaryExpression();
+    } else {
+      return createSyntheticIdentifier();
+    }
+  }
+  /**
+   * Parse a redirecting constructor invocation.
+   * <pre>
+   * redirectingConstructorInvocation ::=
+   * 'this' ('.' identifier)? arguments
+   * </pre>
+   * @return the redirecting constructor invocation that was parsed
+   */
+  RedirectingConstructorInvocation parseRedirectingConstructorInvocation() {
+    Token keyword = expect(Keyword.THIS);
+    Token period = null;
+    SimpleIdentifier constructorName = null;
+    if (matches5(TokenType.PERIOD)) {
+      period = andAdvance;
+      constructorName = parseSimpleIdentifier();
+    }
+    ArgumentList argumentList = parseArgumentList();
+    return new RedirectingConstructorInvocation(keyword, period, constructorName, argumentList);
+  }
+  /**
+   * Parse a relational expression.
+   * <pre>
+   * relationalExpression ::=
+   * shiftExpression ('is' type | 'as' type | relationalOperator shiftExpression)?
+   * | 'super' relationalOperator shiftExpression
+   * </pre>
+   * @return the relational expression that was parsed
+   */
+  Expression parseRelationalExpression() {
+    if (matches(Keyword.SUPER) && _currentToken.next.type.isRelationalOperator()) {
+      Expression expression = new SuperExpression(andAdvance);
+      Token operator = andAdvance;
+      expression = new BinaryExpression(expression, operator, parseShiftExpression());
+      return expression;
+    }
+    Expression expression = parseShiftExpression();
+    if (matches(Keyword.AS)) {
+      Token isOperator = andAdvance;
+      expression = new AsExpression(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());
+    } else if (_currentToken.type.isRelationalOperator()) {
+      Token operator = andAdvance;
+      expression = new BinaryExpression(expression, operator, parseShiftExpression());
+    }
+    return expression;
+  }
+  /**
+   * Parse a return statement.
+   * <pre>
+   * returnStatement ::=
+   * 'return' expression? ';'
+   * </pre>
+   * @return the return statement that was parsed
+   */
+  Statement parseReturnStatement() {
+    Token returnKeyword = expect(Keyword.RETURN);
+    if (matches5(TokenType.SEMICOLON)) {
+      return new ReturnStatement(returnKeyword, null, andAdvance);
+    }
+    Expression expression = parseExpression2();
+    Token semicolon = expect2(TokenType.SEMICOLON);
+    return new ReturnStatement(returnKeyword, expression, semicolon);
+  }
+  /**
+   * Parse a return type.
+   * <pre>
+   * returnType ::=
+   * 'void'
+   * | type
+   * </pre>
+   * @return the return type that was parsed
+   */
+  TypeName parseReturnType() {
+    if (matches(Keyword.VOID)) {
+      return new TypeName(new SimpleIdentifier(andAdvance), null);
+    } else {
+      return parseTypeName();
+    }
+  }
+  /**
+   * Parse a setter.
+   * <pre>
+   * setter ::=
+   * setterSignature functionBody?
+   * setterSignature ::=
+   * 'external'? 'static'? returnType? 'set' identifier formalParameterList
+   * </pre>
+   * @param commentAndMetadata the documentation comment and metadata to be associated with the
+   * declaration
+   * @param externalKeyword the 'external' token
+   * @param staticKeyword the static keyword, or {@code null} if the setter is not static
+   * @param the return type that has already been parsed, or {@code null} if there was no return
+   * type
+   * @return the setter that was parsed
+   */
+  MethodDeclaration parseSetter(CommentAndMetadata commentAndMetadata, Token externalKeyword, Token staticKeyword, TypeName returnType) {
+    Token propertyKeyword = expect(Keyword.SET);
+    SimpleIdentifier name = parseSimpleIdentifier();
+    FormalParameterList parameters = parseFormalParameterList();
+    validateFormalParameterList(parameters);
+    FunctionBody body = parseFunctionBody(true, false);
+    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);
+  }
+  /**
+   * Parse a shift expression.
+   * <pre>
+   * shiftExpression ::=
+   * additiveExpression (shiftOperator additiveExpression)
+   * | 'super' (shiftOperator additiveExpression)+
+   * </pre>
+   * @return the shift expression that was parsed
+   */
+  Expression parseShiftExpression() {
+    Expression expression;
+    if (matches(Keyword.SUPER) && _currentToken.next.type.isShiftOperator()) {
+      expression = new SuperExpression(andAdvance);
+    } else {
+      expression = parseAdditiveExpression();
+    }
+    while (_currentToken.type.isShiftOperator()) {
+      Token operator = andAdvance;
+      expression = new BinaryExpression(expression, operator, parseAdditiveExpression());
+    }
+    return expression;
+  }
+  /**
+   * Parse a simple identifier.
+   * <pre>
+   * identifier ::=
+   * IDENTIFIER
+   * </pre>
+   * @return the simple identifier that was parsed
+   */
+  SimpleIdentifier parseSimpleIdentifier() {
+    if (matchesIdentifier()) {
+      return new SimpleIdentifier(andAdvance);
+    }
+    reportError3(ParserErrorCode.MISSING_IDENTIFIER, []);
+    return createSyntheticIdentifier();
+  }
+  /**
+   * Parse a simple identifier and validate that it is not a built-in identifier.
+   * <pre>
+   * identifier ::=
+   * IDENTIFIER
+   * </pre>
+   * @param errorCode the error code to be used to report a built-in identifier if one is found
+   * @return the simple identifier that was parsed
+   */
+  SimpleIdentifier parseSimpleIdentifier2(ParserErrorCode errorCode) {
+    if (matchesIdentifier()) {
+      Token token = andAdvance;
+      if (token.type == TokenType.KEYWORD) {
+        reportError4(errorCode, token, [token.lexeme]);
+      }
+      return new SimpleIdentifier(token);
+    }
+    reportError3(ParserErrorCode.MISSING_IDENTIFIER, []);
+    return createSyntheticIdentifier();
+  }
+  /**
+   * Parse a statement.
+   * <pre>
+   * statement ::=
+   * label* nonLabeledStatement
+   * </pre>
+   * @return the statement that was parsed
+   */
+  Statement parseStatement2() {
+    List<Label> labels = new List<Label>();
+    while (matchesIdentifier() && matches4(peek(), TokenType.COLON)) {
+      SimpleIdentifier label = parseSimpleIdentifier();
+      Token colon = expect2(TokenType.COLON);
+      labels.add(new Label(label, colon));
+    }
+    Statement statement = parseNonLabeledStatement();
+    if (labels.isEmpty) {
+      return statement;
+    }
+    return new LabeledStatement(labels, statement);
+  }
+  /**
+   * Parse a list of statements within a switch statement.
+   * <pre>
+   * statements ::=
+   * statement
+   * </pre>
+   * @return the statements that were parsed
+   */
+  List<Statement> parseStatements2() {
+    List<Statement> statements = new List<Statement>();
+    Token statementStart = _currentToken;
+    while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET) && !isSwitchMember()) {
+      statements.add(parseStatement2());
+      if (_currentToken == statementStart) {
+        reportError4(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_currentToken.lexeme]);
+        advance();
+      }
+      statementStart = _currentToken;
+    }
+    return statements;
+  }
+  /**
+   * Parse a string literal that contains interpolations.
+   * @return the string literal that was parsed
+   */
+  StringInterpolation parseStringInterpolation(Token string) {
+    List<InterpolationElement> elements = new List<InterpolationElement>();
+    elements.add(new InterpolationString(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));
+      } else {
+        Token openToken = andAdvance;
+        Expression expression = null;
+        if (matches(Keyword.THIS)) {
+          expression = new ThisExpression(andAdvance);
+        } else {
+          expression = parseSimpleIdentifier();
+        }
+        elements.add(new InterpolationExpression(openToken, expression, null));
+      }
+      if (matches5(TokenType.STRING)) {
+        string = andAdvance;
+        elements.add(new InterpolationString(string, computeStringValue(string.lexeme)));
+      }
+    }
+    return new StringInterpolation(elements);
+  }
+  /**
+   * Parse a string literal.
+   * <pre>
+   * stringLiteral ::=
+   * MULTI_LINE_STRING+
+   * | SINGLE_LINE_STRING+
+   * </pre>
+   * @return the string literal that was parsed
+   */
+  StringLiteral parseStringLiteral() {
+    List<StringLiteral> strings = new List<StringLiteral>();
+    while (matches5(TokenType.STRING)) {
+      Token string = andAdvance;
+      if (matches5(TokenType.STRING_INTERPOLATION_EXPRESSION) || matches5(TokenType.STRING_INTERPOLATION_IDENTIFIER)) {
+        strings.add(parseStringInterpolation(string));
+      } else {
+        strings.add(new SimpleStringLiteral(string, computeStringValue(string.lexeme)));
+      }
+    }
+    if (strings.length < 1) {
+      reportError3(ParserErrorCode.EXPECTED_STRING_LITERAL, []);
+      return createSyntheticStringLiteral();
+    } else if (strings.length == 1) {
+      return strings[0];
+    } else {
+      return new AdjacentStrings(strings);
+    }
+  }
+  /**
+   * Parse a super constructor invocation.
+   * <pre>
+   * superConstructorInvocation ::=
+   * 'super' ('.' identifier)? arguments
+   * </pre>
+   * @return the super constructor invocation that was parsed
+   */
+  SuperConstructorInvocation parseSuperConstructorInvocation() {
+    Token keyword = expect(Keyword.SUPER);
+    Token period = null;
+    SimpleIdentifier constructorName = null;
+    if (matches5(TokenType.PERIOD)) {
+      period = andAdvance;
+      constructorName = parseSimpleIdentifier();
+    }
+    ArgumentList argumentList = parseArgumentList();
+    return new SuperConstructorInvocation(keyword, period, constructorName, argumentList);
+  }
+  /**
+   * Parse a switch statement.
+   * <pre>
+   * switchStatement ::=
+   * 'switch' '(' expression ')' '{' switchCase* defaultCase? '}'
+   * switchCase ::=
+   * label* ('case' expression ':') statements
+   * defaultCase ::=
+   * label* 'default' ':' statements
+   * </pre>
+   * @return the switch statement that was parsed
+   */
+  SwitchStatement parseSwitchStatement() {
+    bool wasInSwitch = _inSwitch;
+    _inSwitch = true;
+    try {
+      Set<String> definedLabels = new Set<String>();
+      Token keyword = expect(Keyword.SWITCH);
+      Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
+      Expression expression = parseExpression2();
+      Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
+      Token leftBracket = expect2(TokenType.OPEN_CURLY_BRACKET);
+      List<SwitchMember> members = new List<SwitchMember>();
+      while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET)) {
+        List<Label> labels = new List<Label>();
+        while (matchesIdentifier() && matches4(peek(), TokenType.COLON)) {
+          SimpleIdentifier identifier = parseSimpleIdentifier();
+          String label = identifier.token.lexeme;
+          if (definedLabels.contains(label)) {
+            reportError4(ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT, identifier.token, [label]);
+          } else {
+            javaSetAdd(definedLabels, label);
+          }
+          Token colon = expect2(TokenType.COLON);
+          labels.add(new Label(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()));
+        } else if (matches(Keyword.DEFAULT)) {
+          Token defaultKeyword = andAdvance;
+          Token colon = expect2(TokenType.COLON);
+          members.add(new SwitchDefault(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)) {
+            advance();
+          }
+        }
+      }
+      Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET);
+      return new SwitchStatement(keyword, leftParenthesis, expression, rightParenthesis, leftBracket, members, rightBracket);
+    } finally {
+      _inSwitch = wasInSwitch;
+    }
+  }
+  /**
+   * Parse a throw expression.
+   * <pre>
+   * throwExpression ::=
+   * 'throw' expression? ';'
+   * </pre>
+   * @return the throw expression that was parsed
+   */
+  Expression parseThrowExpression() {
+    Token keyword = expect(Keyword.THROW);
+    if (matches5(TokenType.SEMICOLON) || matches5(TokenType.CLOSE_PAREN)) {
+      return new ThrowExpression(keyword, null);
+    }
+    Expression expression = parseExpression2();
+    return new ThrowExpression(keyword, expression);
+  }
+  /**
+   * Parse a throw expression.
+   * <pre>
+   * throwExpressionWithoutCascade ::=
+   * 'throw' expressionWithoutCascade? ';'
+   * </pre>
+   * @return the throw expression that was parsed
+   */
+  Expression parseThrowExpressionWithoutCascade() {
+    Token keyword = expect(Keyword.THROW);
+    if (matches5(TokenType.SEMICOLON) || matches5(TokenType.CLOSE_PAREN)) {
+      return new ThrowExpression(keyword, null);
+    }
+    Expression expression = parseExpressionWithoutCascade();
+    return new ThrowExpression(keyword, expression);
+  }
+  /**
+   * Parse a try statement.
+   * <pre>
+   * tryStatement ::=
+   * 'try' block (onPart+ finallyPart? | finallyPart)
+   * onPart ::=
+   * catchPart block
+   * | 'on' qualified catchPart? block
+   * catchPart ::=
+   * 'catch' '(' identifier (',' identifier)? ')'
+   * finallyPart ::=
+   * 'finally' block
+   * </pre>
+   * @return the try statement that was parsed
+   */
+  Statement parseTryStatement() {
+    Token tryKeyword = expect(Keyword.TRY);
+    Block body = parseBlock();
+    List<CatchClause> catchClauses = new List<CatchClause>();
+    Block finallyClause = null;
+    while (matches2(Parser._ON) || matches(Keyword.CATCH)) {
+      Token onKeyword = null;
+      TypeName exceptionType = null;
+      if (matches2(Parser._ON)) {
+        onKeyword = andAdvance;
+        exceptionType = new TypeName(parsePrefixedIdentifier(), null);
+      }
+      Token catchKeyword = null;
+      Token leftParenthesis = null;
+      SimpleIdentifier exceptionParameter = null;
+      Token comma = null;
+      SimpleIdentifier stackTraceParameter = null;
+      Token rightParenthesis = null;
+      if (matches(Keyword.CATCH)) {
+        catchKeyword = andAdvance;
+        leftParenthesis = expect2(TokenType.OPEN_PAREN);
+        exceptionParameter = parseSimpleIdentifier();
+        if (matches5(TokenType.COMMA)) {
+          comma = andAdvance;
+          stackTraceParameter = parseSimpleIdentifier();
+        }
+        rightParenthesis = expect2(TokenType.CLOSE_PAREN);
+      }
+      Block catchBody = parseBlock();
+      catchClauses.add(new CatchClause(onKeyword, exceptionType, catchKeyword, leftParenthesis, exceptionParameter, comma, stackTraceParameter, rightParenthesis, catchBody));
+    }
+    Token finallyKeyword = null;
+    if (matches(Keyword.FINALLY)) {
+      finallyKeyword = andAdvance;
+      finallyClause = parseBlock();
+    } else {
+      if (catchClauses.isEmpty) {
+        reportError3(ParserErrorCode.MISSING_CATCH_OR_FINALLY, []);
+      }
+    }
+    return new TryStatement(tryKeyword, body, catchClauses, finallyKeyword, finallyClause);
+  }
+  /**
+   * Parse a type alias.
+   * <pre>
+   * typeAlias ::=
+   * 'typedef' typeAliasBody
+   * typeAliasBody ::=
+   * classTypeAlias
+   * | functionTypeAlias
+   * classTypeAlias ::=
+   * identifier typeParameters? '=' 'abstract'? mixinApplication
+   * mixinApplication ::=
+   * qualified withClause implementsClause? ';'
+   * functionTypeAlias ::=
+   * functionPrefix typeParameterList? formalParameterList ';'
+   * functionPrefix ::=
+   * returnType? name
+   * </pre>
+   * @param commentAndMetadata the metadata to be associated with the member
+   * @return the type alias that was parsed
+   */
+  TypeAlias parseTypeAlias(CommentAndMetadata commentAndMetadata) {
+    Token keyword = expect(Keyword.TYPEDEF);
+    if (matchesIdentifier()) {
+      Token next = peek();
+      if (matches4(next, TokenType.LT)) {
+        next = skipTypeParameterList(next);
+        if (next != null && matches4(next, TokenType.EQ)) {
+          return parseClassTypeAlias(commentAndMetadata, keyword);
+        }
+      } else if (matches4(next, TokenType.EQ)) {
+        return parseClassTypeAlias(commentAndMetadata, keyword);
+      }
+    }
+    return parseFunctionTypeAlias(commentAndMetadata, keyword);
+  }
+  /**
+   * Parse a list of type arguments.
+   * <pre>
+   * typeArguments ::=
+   * '<' typeList '>'
+   * typeList ::=
+   * type (',' type)
+   * </pre>
+   * @return the type argument list that was parsed
+   */
+  TypeArgumentList parseTypeArgumentList() {
+    Token leftBracket = expect2(TokenType.LT);
+    List<TypeName> arguments = new List<TypeName>();
+    arguments.add(parseTypeName());
+    while (optional(TokenType.COMMA)) {
+      arguments.add(parseTypeName());
+    }
+    Token rightBracket = expect2(TokenType.GT);
+    return new TypeArgumentList(leftBracket, arguments, rightBracket);
+  }
+  /**
+   * Parse a type name.
+   * <pre>
+   * type ::=
+   * qualified typeArguments?
+   * </pre>
+   * @return the type name that was parsed
+   */
+  TypeName parseTypeName() {
+    Identifier typeName = parsePrefixedIdentifier();
+    TypeArgumentList typeArguments = null;
+    if (matches5(TokenType.LT)) {
+      typeArguments = parseTypeArgumentList();
+    }
+    return new TypeName(typeName, typeArguments);
+  }
+  /**
+   * Parse a type parameter.
+   * <pre>
+   * typeParameter ::=
+   * metadata name ('extends' bound)?
+   * </pre>
+   * @return the type parameter that was parsed
+   */
+  TypeParameter parseTypeParameter() {
+    CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
+    SimpleIdentifier name = parseSimpleIdentifier2(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME);
+    if (matches(Keyword.EXTENDS)) {
+      Token keyword = andAdvance;
+      TypeName bound = parseTypeName();
+      return new TypeParameter(commentAndMetadata.comment, commentAndMetadata.metadata, name, keyword, bound);
+    }
+    return new TypeParameter(commentAndMetadata.comment, commentAndMetadata.metadata, name, null, null);
+  }
+  /**
+   * Parse a list of type parameters.
+   * <pre>
+   * typeParameterList ::=
+   * '<' typeParameter (',' typeParameter)* '>'
+   * </pre>
+   * @return the list of type parameters that were parsed
+   */
+  TypeParameterList parseTypeParameterList() {
+    Token leftBracket = expect2(TokenType.LT);
+    List<TypeParameter> typeParameters = new List<TypeParameter>();
+    typeParameters.add(parseTypeParameter());
+    while (optional(TokenType.COMMA)) {
+      typeParameters.add(parseTypeParameter());
+    }
+    Token rightBracket = expect2(TokenType.GT);
+    return new TypeParameterList(leftBracket, typeParameters, rightBracket);
+  }
+  /**
+   * Parse a unary expression.
+   * <pre>
+   * unaryExpression ::=
+   * prefixOperator unaryExpression
+   * | postfixExpression
+   * | unaryOperator 'super'
+   * | '-' 'super'
+   * | incrementOperator assignableExpression
+   * </pre>
+   * @return the unary expression that was parsed
+   */
+  Expression parseUnaryExpression() {
+    if (matches5(TokenType.MINUS) || matches5(TokenType.BANG) || matches5(TokenType.TILDE)) {
+      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(operator, new SuperExpression(andAdvance));
+      }
+      return new PrefixExpression(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);
+          secondOperator.setNext(_currentToken);
+          firstOperator.setNext(secondOperator);
+          operator.previous.setNext(firstOperator);
+          return new PrefixExpression(firstOperator, new PrefixExpression(secondOperator, new SuperExpression(andAdvance)));
+        } else {
+          reportError3(ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, [operator.lexeme]);
+          return new PrefixExpression(operator, new SuperExpression(andAdvance));
+        }
+      }
+      return new PrefixExpression(operator, parseAssignableExpression(false));
+    } else if (matches5(TokenType.PLUS)) {
+      reportError3(ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR, []);
+    }
+    return parsePostfixExpression();
+  }
+  /**
+   * Parse a variable declaration.
+   * <pre>
+   * variableDeclaration ::=
+   * identifier ('=' expression)?
+   * </pre>
+   * @return the variable declaration that was parsed
+   */
+  VariableDeclaration parseVariableDeclaration() {
+    CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
+    SimpleIdentifier name = parseSimpleIdentifier();
+    Token equals = null;
+    Expression initializer = null;
+    if (matches5(TokenType.EQ)) {
+      equals = andAdvance;
+      initializer = parseExpression2();
+    }
+    return new VariableDeclaration(commentAndMetadata.comment, commentAndMetadata.metadata, name, equals, initializer);
+  }
+  /**
+   * Parse a variable declaration list.
+   * <pre>
+   * variableDeclarationList ::=
+   * finalConstVarOrType variableDeclaration (',' variableDeclaration)
+   * </pre>
+   * @return the variable declaration list that was parsed
+   */
+  VariableDeclarationList parseVariableDeclarationList() {
+    FinalConstVarOrType holder = parseFinalConstVarOrType(false);
+    return parseVariableDeclarationList2(holder.keyword, holder.type);
+  }
+  /**
+   * Parse a variable declaration list.
+   * <pre>
+   * variableDeclarationList ::=
+   * finalConstVarOrType variableDeclaration (',' variableDeclaration)
+   * </pre>
+   * @param keyword the token representing the 'final', 'const' or 'var' keyword, or {@code null} if
+   * there is no keyword
+   * @param type the type of the variables in the list
+   * @return the variable declaration list that was parsed
+   */
+  VariableDeclarationList parseVariableDeclarationList2(Token keyword, TypeName type) {
+    List<VariableDeclaration> variables = new List<VariableDeclaration>();
+    variables.add(parseVariableDeclaration());
+    while (matches5(TokenType.COMMA)) {
+      advance();
+      variables.add(parseVariableDeclaration());
+    }
+    return new VariableDeclarationList(keyword, type, variables);
+  }
+  /**
+   * Parse a variable declaration statement.
+   * <pre>
+   * variableDeclarationStatement ::=
+   * variableDeclarationList ';'
+   * </pre>
+   * @return the variable declaration statement that was parsed
+   */
+  VariableDeclarationStatement parseVariableDeclarationStatement() {
+    VariableDeclarationList variableList = parseVariableDeclarationList();
+    Token semicolon = expect2(TokenType.SEMICOLON);
+    return new VariableDeclarationStatement(variableList, semicolon);
+  }
+  /**
+   * Parse a while statement.
+   * <pre>
+   * whileStatement ::=
+   * 'while' '(' expression ')' statement
+   * </pre>
+   * @return the while statement that was parsed
+   */
+  Statement parseWhileStatement() {
+    bool wasInLoop = _inLoop;
+    _inLoop = true;
+    try {
+      Token keyword = expect(Keyword.WHILE);
+      Token leftParenthesis = expect2(TokenType.OPEN_PAREN);
+      Expression condition = parseExpression2();
+      Token rightParenthesis = expect2(TokenType.CLOSE_PAREN);
+      Statement body = parseStatement2();
+      return new WhileStatement(keyword, leftParenthesis, condition, rightParenthesis, body);
+    } finally {
+      _inLoop = wasInLoop;
+    }
+  }
+  /**
+   * Parse a with clause.
+   * <pre>
+   * withClause ::=
+   * 'with' typeName (',' typeName)
+   * </pre>
+   * @return the with clause that was parsed
+   */
+  WithClause parseWithClause() {
+    Token with6 = expect(Keyword.WITH);
+    List<TypeName> types = new List<TypeName>();
+    types.add(parseTypeName());
+    while (optional(TokenType.COMMA)) {
+      types.add(parseTypeName());
+    }
+    return new WithClause(with6, types);
+  }
+  /**
+   * Return the token that is immediately after the current token. This is equivalent to{@link #peek(int) peek(1)}.
+   * @return the token that is immediately after the current token
+   */
+  Token peek() => _currentToken.next;
+  /**
+   * Return the token that is the given distance after the current token.
+   * @param distance the number of tokens to look ahead, where {@code 0} is the current token,{@code 1} is the next token, etc.
+   * @return the token that is the given distance after the current token
+   */
+  Token peek2(int distance) {
+    Token token = _currentToken;
+    for (int i = 0; i < distance; i++) {
+      token = token.next;
+    }
+    return token;
+  }
+  /**
+   * 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(ParserErrorCode 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 arguments the arguments to the error, used to compose the error message
+   */
+  void reportError3(ParserErrorCode errorCode, List<Object> arguments) {
+    reportError4(errorCode, _currentToken, 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 reportError4(ParserErrorCode errorCode, Token token, List<Object> arguments) {
+    _errorListener.onError(new AnalysisError.con2(_source, token.offset, token.length, errorCode, [arguments]));
+  }
+  /**
+   * Parse the 'final', 'const', 'var' or type preceding a variable declaration, starting at the
+   * given token, without actually creating a type or changing the current token. Return the token
+   * following the type that was parsed, or {@code null} if the given token is not the first token
+   * in a valid type.
+   * <pre>
+   * finalConstVarOrType ::=
+   * | 'final' type?
+   * | 'const' type?
+   * | 'var'
+   * | type
+   * </pre>
+   * @param startToken the token at which parsing is to begin
+   * @return the token following the type that was parsed
+   */
+  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);
+      }
+    } 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)))) {
+        return skipReturnType(startToken);
+      }
+    }
+    return null;
+  }
+  /**
+   * Parse a list of formal parameters, starting at the given token, without actually creating a
+   * formal parameter list or changing the current token. Return the token following the formal
+   * parameter list that was parsed, or {@code null} if the given token is not the first token in a
+   * valid list of formal parameter.
+   * <p>
+   * Note that unlike other skip methods, this method uses a heuristic. In the worst case, the
+   * parameters could be prefixed by metadata, which would require us to be able to skip arbitrary
+   * expressions. Rather than duplicate the logic of most of the parse methods we simply look for
+   * something that is likely to be a list of parameters and then skip to returning the token after
+   * the closing parenthesis.
+   * <p>
+   * This method must be kept in sync with {@link #parseFormalParameterList()}.
+   * <pre>
+   * formalParameterList ::=
+   * '(' ')'
+   * | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
+   * | '(' optionalFormalParameters ')'
+   * normalFormalParameters ::=
+   * normalFormalParameter (',' normalFormalParameter)
+   * optionalFormalParameters ::=
+   * optionalPositionalFormalParameters
+   * | namedFormalParameters
+   * optionalPositionalFormalParameters ::=
+   * '[' defaultFormalParameter (',' defaultFormalParameter)* ']'
+   * namedFormalParameters ::=
+   * '{' defaultNamedParameter (',' defaultNamedParameter)* '}'
+   * </pre>
+   * @param startToken the token at which parsing is to begin
+   * @return the token following the formal parameter list that was parsed
+   */
+  Token skipFormalParameterList(Token startToken) {
+    if (!matches4(startToken, TokenType.OPEN_PAREN)) {
+      return null;
+    }
+    Token next4 = startToken.next;
+    if (matches4(next4, TokenType.CLOSE_PAREN)) {
+      return next4.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])))) {
+      return skipPastMatchingToken(startToken);
+    }
+    if (matchesIdentifier2(next4) && matches4(next4.next, TokenType.OPEN_PAREN)) {
+      Token afterParameters = skipFormalParameterList(next4.next);
+      if (afterParameters != null && (matchesAny(afterParameters, [TokenType.COMMA, TokenType.CLOSE_PAREN]))) {
+        return skipPastMatchingToken(startToken);
+      }
+    }
+    Token afterType = skipFinalConstVarOrType(next4);
+    if (afterType == null) {
+      return null;
+    }
+    if (skipSimpleIdentifier(afterType) == null) {
+      return null;
+    }
+    return skipPastMatchingToken(startToken);
+  }
+  /**
+   * If the given token is a begin token with an associated end token, then return the token
+   * following the end token. Otherwise, return {@code null}.
+   * @param startToken the token that is assumed to be a being token
+   * @return the token following the matching end token
+   */
+  Token skipPastMatchingToken(Token startToken) {
+    if (startToken is! BeginToken) {
+      return null;
+    }
+    Token closeParen = (startToken as BeginToken).endToken;
+    if (closeParen == null) {
+      return null;
+    }
+    return closeParen.next;
+  }
+  /**
+   * Parse a prefixed identifier, starting at the given token, without actually creating a prefixed
+   * identifier or changing the current token. Return the token following the prefixed identifier
+   * that was parsed, or {@code null} if the given token is not the first token in a valid prefixed
+   * identifier.
+   * <p>
+   * This method must be kept in sync with {@link #parsePrefixedIdentifier()}.
+   * <pre>
+   * prefixedIdentifier ::=
+   * identifier ('.' identifier)?
+   * </pre>
+   * @param startToken the token at which parsing is to begin
+   * @return the token following the prefixed identifier that was parsed
+   */
+  Token skipPrefixedIdentifier(Token startToken) {
+    Token token = skipSimpleIdentifier(startToken);
+    if (token == null) {
+      return null;
+    } else if (!matches4(token, TokenType.PERIOD)) {
+      return token;
+    }
+    return skipSimpleIdentifier(token.next);
+  }
+  /**
+   * Parse a return type, starting at the given token, without actually creating a return type or
+   * changing the current token. Return the token following the return type that was parsed, or{@code null} if the given token is not the first token in a valid return type.
+   * <p>
+   * This method must be kept in sync with {@link #parseReturnType()}.
+   * <pre>
+   * returnType ::=
+   * 'void'
+   * | type
+   * </pre>
+   * @param startToken the token at which parsing is to begin
+   * @return the token following the return type that was parsed
+   */
+  Token skipReturnType(Token startToken) {
+    if (matches3(startToken, Keyword.VOID)) {
+      return startToken.next;
+    } else {
+      return skipTypeName(startToken);
+    }
+  }
+  /**
+   * Parse a simple identifier, starting at the given token, without actually creating a simple
+   * identifier or changing the current token. Return the token following the simple identifier that
+   * was parsed, or {@code null} if the given token is not the first token in a valid simple
+   * identifier.
+   * <p>
+   * This method must be kept in sync with {@link #parseSimpleIdentifier()}.
+   * <pre>
+   * identifier ::=
+   * IDENTIFIER
+   * </pre>
+   * @param startToken the token at which parsing is to begin
+   * @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())) {
+      return startToken.next;
+    }
+    return null;
+  }
+  /**
+   * Parse a string literal that contains interpolations, starting at the given token, without
+   * actually creating a string literal or changing the current token. Return the token following
+   * the string literal that was parsed, or {@code null} if the given token is not the first token
+   * in a valid string literal.
+   * <p>
+   * This method must be kept in sync with {@link #parseStringInterpolation(Token)}.
+   * @param startToken the token at which parsing is to begin
+   * @return the string literal that was parsed
+   */
+  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) {
+        token = token.next;
+        type19 = token.type;
+        int bracketNestingLevel = 1;
+        while (bracketNestingLevel > 0) {
+          if (type19 == TokenType.EOF) {
+            return null;
+          } else if (type19 == TokenType.OPEN_CURLY_BRACKET) {
+            bracketNestingLevel++;
+          } else if (type19 == TokenType.CLOSE_CURLY_BRACKET) {
+            bracketNestingLevel--;
+          } else if (type19 == TokenType.STRING) {
+            token = skipStringLiteral(token);
+            if (token == null) {
+              return null;
+            }
+          } else {
+            token = token.next;
+          }
+          type19 = token.type;
+        }
+        token = token.next;
+        type19 = token.type;
+      } else {
+        token = token.next;
+        if (token.type != TokenType.IDENTIFIER) {
+          return null;
+        }
+        token = token.next;
+      }
+      type19 = token.type;
+      if (type19 == TokenType.STRING) {
+        token = token.next;
+        type19 = token.type;
+      }
+    }
+    return token;
+  }
+  /**
+   * Parse a string literal, starting at the given token, without actually creating a string literal
+   * or changing the current token. Return the token following the string literal that was parsed,
+   * or {@code null} if the given token is not the first token in a valid string literal.
+   * <p>
+   * This method must be kept in sync with {@link #parseStringLiteral()}.
+   * <pre>
+   * stringLiteral ::=
+   * MULTI_LINE_STRING+
+   * | SINGLE_LINE_STRING+
+   * </pre>
+   * @param startToken the token at which parsing is to begin
+   * @return the token following the string literal that was parsed
+   */
+  Token skipStringLiteral(Token startToken) {
+    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) {
+        token = skipStringInterpolation(token);
+      }
+    }
+    if (token == startToken) {
+      return null;
+    }
+    return token;
+  }
+  /**
+   * Parse a list of type arguments, starting at the given token, without actually creating a type argument list
+   * or changing the current token. Return the token following the type argument list that was parsed,
+   * or {@code null} if the given token is not the first token in a valid type argument list.
+   * <p>
+   * This method must be kept in sync with {@link #parseTypeArgumentList()}.
+   * <pre>
+   * typeArguments ::=
+   * '<' typeList '>'
+   * typeList ::=
+   * type (',' type)
+   * </pre>
+   * @param startToken the token at which parsing is to begin
+   * @return the token following the type argument list that was parsed
+   */
+  Token skipTypeArgumentList(Token startToken) {
+    Token token = startToken;
+    if (!matches4(token, TokenType.LT)) {
+      return null;
+    }
+    token = skipTypeName(token.next);
+    if (token == null) {
+      return null;
+    }
+    while (matches4(token, TokenType.COMMA)) {
+      token = skipTypeName(token.next);
+      if (token == null) {
+        return null;
+      }
+    }
+    if (token.type == TokenType.GT) {
+      return token.next;
+    } else if (token.type == TokenType.GT_GT) {
+      Token second = new Token(TokenType.GT, token.offset + 1);
+      second.setNextWithoutSettingPrevious(token.next);
+      return second;
+    }
+    return null;
+  }
+  /**
+   * Parse a type name, starting at the given token, without actually creating a type name or
+   * changing the current token. Return the token following the type name that was parsed, or{@code null} if the given token is not the first token in a valid type name.
+   * <p>
+   * This method must be kept in sync with {@link #parseTypeName()}.
+   * <pre>
+   * type ::=
+   * qualified typeArguments?
+   * </pre>
+   * @param startToken the token at which parsing is to begin
+   * @return the token following the type name that was parsed
+   */
+  Token skipTypeName(Token startToken) {
+    Token token = skipPrefixedIdentifier(startToken);
+    if (token == null) {
+      return null;
+    }
+    if (matches4(token, TokenType.LT)) {
+      token = skipTypeArgumentList(token);
+    }
+    return token;
+  }
+  /**
+   * Parse a list of type parameters, starting at the given token, without actually creating a type
+   * parameter list or changing the current token. Return the token following the type parameter
+   * list that was parsed, or {@code null} if the given token is not the first token in a valid type
+   * parameter list.
+   * <p>
+   * This method must be kept in sync with {@link #parseTypeParameterList()}.
+   * <pre>
+   * typeParameterList ::=
+   * '<' typeParameter (',' typeParameter)* '>'
+   * </pre>
+   * @param startToken the token at which parsing is to begin
+   * @return the token following the type parameter list that was parsed
+   */
+  Token skipTypeParameterList(Token startToken) {
+    if (!matches4(startToken, TokenType.LT)) {
+      return null;
+    }
+    int depth = 1;
+    Token next5 = startToken.next;
+    while (depth > 0) {
+      if (matches4(next5, TokenType.EOF)) {
+        return null;
+      } else if (matches4(next5, TokenType.LT)) {
+        depth++;
+      } else if (matches4(next5, TokenType.GT)) {
+        depth--;
+      } else if (matches4(next5, TokenType.GT_EQ)) {
+        if (depth == 1) {
+          Token fakeEquals = new Token(TokenType.EQ, next5.offset + 2);
+          fakeEquals.setNextWithoutSettingPrevious(next5.next);
+          return fakeEquals;
+        }
+        depth--;
+      } else if (matches4(next5, TokenType.GT_GT)) {
+        depth -= 2;
+      } else if (matches4(next5, 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);
+          return fakeEquals;
+        }
+        depth -= 2;
+      }
+      next5 = next5.next;
+    }
+    return next5;
+  }
+  /**
+   * Translate the characters at the given index in the given string, appending the translated
+   * character to the given builder. The index is assumed to be valid.
+   * @param builder the builder to which the translated character is to be appended
+   * @param lexeme the string containing the character(s) to be translated
+   * @param index the index of the character to be translated
+   * @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) {
+      builder.addCharCode(currentChar);
+      return index + 1;
+    }
+    int length8 = lexeme.length;
+    int currentIndex = index + 1;
+    if (currentIndex >= length8) {
+      return length8;
+    }
+    currentChar = lexeme.charCodeAt(currentIndex);
+    if (currentChar == 0x6e) {
+      builder.addCharCode(0xa);
+    } else if (currentChar == 0x72) {
+      builder.addCharCode(0xd);
+    } else if (currentChar == 0x66) {
+      builder.addCharCode(0xc);
+    } else if (currentChar == 0x62) {
+      builder.addCharCode(0x8);
+    } else if (currentChar == 0x74) {
+      builder.addCharCode(0x9);
+    } else if (currentChar == 0x76) {
+      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);
+      if (!isHexDigit(firstDigit) || !isHexDigit(secondDigit)) {
+        reportError3(ParserErrorCode.INVALID_HEX_ESCAPE, []);
+      } else {
+        builder.addCharCode(((Character.digit(firstDigit, 16) << 4) + Character.digit(secondDigit, 16)) as int);
+      }
+      return currentIndex + 3;
+    } else if (currentChar == 0x75) {
+      currentIndex++;
+      if (currentIndex >= length8) {
+        reportError3(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+        return length8;
+      }
+      currentChar = lexeme.charCodeAt(currentIndex);
+      if (currentChar == 0x7b) {
+        currentIndex++;
+        if (currentIndex >= length8) {
+          reportError3(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+          return length8;
+        }
+        currentChar = lexeme.charCodeAt(currentIndex);
+        int digitCount = 0;
+        int value = 0;
+        while (currentChar != 0x7d) {
+          if (!isHexDigit(currentChar)) {
+            reportError3(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+            currentIndex++;
+            while (currentIndex < length8 && lexeme.charCodeAt(currentIndex) != 0x7d) {
+              currentIndex++;
+            }
+            return currentIndex + 1;
+          }
+          digitCount++;
+          value = (value << 4) + Character.digit(currentChar, 16);
+          currentIndex++;
+          if (currentIndex >= length8) {
+            reportError3(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+            return length8;
+          }
+          currentChar = lexeme.charCodeAt(currentIndex);
+        }
+        if (digitCount < 1 || digitCount > 6) {
+          reportError3(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+        }
+        appendScalarValue(builder, lexeme.substring(index, currentIndex + 1), value, index, currentIndex);
+        return currentIndex + 1;
+      } else {
+        if (currentIndex + 3 >= length8) {
+          reportError3(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+          return length8;
+        }
+        int firstDigit = currentChar;
+        int secondDigit = lexeme.charCodeAt(currentIndex + 1);
+        int thirdDigit = lexeme.charCodeAt(currentIndex + 2);
+        int fourthDigit = lexeme.charCodeAt(currentIndex + 3);
+        if (!isHexDigit(firstDigit) || !isHexDigit(secondDigit) || !isHexDigit(thirdDigit) || !isHexDigit(fourthDigit)) {
+          reportError3(ParserErrorCode.INVALID_UNICODE_ESCAPE, []);
+        } else {
+          appendScalarValue(builder, lexeme.substring(index, currentIndex + 1), ((((((Character.digit(firstDigit, 16) << 4) + Character.digit(secondDigit, 16)) << 4) + Character.digit(thirdDigit, 16)) << 4) + Character.digit(fourthDigit, 16)), index, currentIndex + 3);
+        }
+        return currentIndex + 4;
+      }
+    } else {
+      builder.addCharCode(currentChar);
+    }
+    return currentIndex + 1;
+  }
+  /**
+   * Validate that the given parameter list does not contain any field initializers.
+   * @param parameterList the parameter list to be validated
+   */
+  void validateFormalParameterList(FormalParameterList parameterList) {
+    for (FormalParameter parameter in parameterList.parameters) {
+      if (parameter is FieldFormalParameter) {
+        reportError(ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, (parameter as FieldFormalParameter).identifier, []);
+      }
+    }
+  }
+  /**
+   * Validate that the given set of modifiers is appropriate for a class and return the 'abstract'
+   * keyword if there is one.
+   * @param modifiers the modifiers being validated
+   */
+  Token validateModifiersForClass(Modifiers modifiers) {
+    validateModifiersForTopLevelDeclaration(modifiers);
+    if (modifiers.constKeyword != null) {
+      reportError4(ParserErrorCode.CONST_CLASS, modifiers.constKeyword, []);
+    }
+    if (modifiers.externalKeyword != null) {
+      reportError4(ParserErrorCode.EXTERNAL_CLASS, modifiers.externalKeyword, []);
+    }
+    if (modifiers.finalKeyword != null) {
+      reportError4(ParserErrorCode.FINAL_CLASS, modifiers.finalKeyword, []);
+    }
+    if (modifiers.varKeyword != null) {
+      reportError4(ParserErrorCode.VAR_CLASS, modifiers.varKeyword, []);
+    }
+    return modifiers.abstractKeyword;
+  }
+  /**
+   * Validate that the given set of modifiers is appropriate for a constructor and return the
+   * 'const' keyword if there is one.
+   * @param modifiers the modifiers being validated
+   * @return the 'const' or 'final' keyword associated with the constructor
+   */
+  Token validateModifiersForConstructor(Modifiers modifiers) {
+    if (modifiers.abstractKeyword != null) {
+      reportError3(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
+    }
+    if (modifiers.finalKeyword != null) {
+      reportError4(ParserErrorCode.FINAL_CONSTRUCTOR, modifiers.finalKeyword, []);
+    }
+    if (modifiers.staticKeyword != null) {
+      reportError4(ParserErrorCode.STATIC_CONSTRUCTOR, modifiers.staticKeyword, []);
+    }
+    if (modifiers.varKeyword != null) {
+      reportError4(ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE, modifiers.varKeyword, []);
+    }
+    Token externalKeyword6 = modifiers.externalKeyword;
+    Token constKeyword4 = modifiers.constKeyword;
+    Token factoryKeyword4 = modifiers.factoryKeyword;
+    if (externalKeyword6 != null && constKeyword4 != null && constKeyword4.offset < externalKeyword6.offset) {
+      reportError4(ParserErrorCode.EXTERNAL_AFTER_CONST, externalKeyword6, []);
+    }
+    if (externalKeyword6 != null && factoryKeyword4 != null && factoryKeyword4.offset < externalKeyword6.offset) {
+      reportError4(ParserErrorCode.EXTERNAL_AFTER_FACTORY, externalKeyword6, []);
+    }
+    return constKeyword4;
+  }
+  /**
+   * Validate that the given set of modifiers is appropriate for a field and return the 'final',
+   * 'const' or 'var' keyword if there is one.
+   * @param modifiers the modifiers being validated
+   * @return the 'final', 'const' or 'var' keyword associated with the field
+   */
+  Token validateModifiersForField(Modifiers modifiers) {
+    if (modifiers.abstractKeyword != null) {
+      reportError3(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
+    }
+    if (modifiers.externalKeyword != null) {
+      reportError4(ParserErrorCode.EXTERNAL_FIELD, modifiers.externalKeyword, []);
+    }
+    if (modifiers.factoryKeyword != null) {
+      reportError4(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKeyword, []);
+    }
+    Token staticKeyword3 = modifiers.staticKeyword;
+    Token constKeyword5 = modifiers.constKeyword;
+    Token finalKeyword3 = modifiers.finalKeyword;
+    Token varKeyword3 = modifiers.varKeyword;
+    if (constKeyword5 != null) {
+      if (finalKeyword3 != null) {
+        reportError4(ParserErrorCode.CONST_AND_FINAL, finalKeyword3, []);
+      }
+      if (varKeyword3 != null) {
+        reportError4(ParserErrorCode.CONST_AND_VAR, varKeyword3, []);
+      }
+      if (staticKeyword3 != null && constKeyword5.offset < staticKeyword3.offset) {
+        reportError4(ParserErrorCode.STATIC_AFTER_CONST, staticKeyword3, []);
+      }
+    } else if (finalKeyword3 != null) {
+      if (varKeyword3 != null) {
+        reportError4(ParserErrorCode.FINAL_AND_VAR, varKeyword3, []);
+      }
+      if (staticKeyword3 != null && finalKeyword3.offset < staticKeyword3.offset) {
+        reportError4(ParserErrorCode.STATIC_AFTER_FINAL, staticKeyword3, []);
+      }
+    } else if (varKeyword3 != null && staticKeyword3 != null && varKeyword3.offset < staticKeyword3.offset) {
+      reportError4(ParserErrorCode.STATIC_AFTER_VAR, staticKeyword3, []);
+    }
+    return lexicallyFirst([constKeyword5, finalKeyword3, varKeyword3]);
+  }
+  /**
+   * Validate that the given set of modifiers is appropriate for a getter, setter, or method.
+   * @param modifiers the modifiers being validated
+   */
+  void validateModifiersForGetterOrSetterOrMethod(Modifiers modifiers) {
+    if (modifiers.abstractKeyword != null) {
+      reportError3(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
+    }
+    if (modifiers.constKeyword != null) {
+      reportError4(ParserErrorCode.CONST_METHOD, modifiers.constKeyword, []);
+    }
+    if (modifiers.factoryKeyword != null) {
+      reportError4(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKeyword, []);
+    }
+    if (modifiers.finalKeyword != null) {
+      reportError4(ParserErrorCode.FINAL_METHOD, modifiers.finalKeyword, []);
+    }
+    if (modifiers.varKeyword != null) {
+      reportError4(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
+    }
+    Token externalKeyword7 = modifiers.externalKeyword;
+    Token staticKeyword4 = modifiers.staticKeyword;
+    if (externalKeyword7 != null && staticKeyword4 != null && staticKeyword4.offset < externalKeyword7.offset) {
+      reportError4(ParserErrorCode.EXTERNAL_AFTER_STATIC, externalKeyword7, []);
+    }
+  }
+  /**
+   * Validate that the given set of modifiers is appropriate for a getter, setter, or method.
+   * @param modifiers the modifiers being validated
+   */
+  void validateModifiersForOperator(Modifiers modifiers) {
+    if (modifiers.abstractKeyword != null) {
+      reportError3(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []);
+    }
+    if (modifiers.constKeyword != null) {
+      reportError4(ParserErrorCode.CONST_METHOD, modifiers.constKeyword, []);
+    }
+    if (modifiers.factoryKeyword != null) {
+      reportError4(ParserErrorCode.NON_CONSTRUCTOR_FACTORY, modifiers.factoryKeyword, []);
+    }
+    if (modifiers.finalKeyword != null) {
+      reportError4(ParserErrorCode.FINAL_METHOD, modifiers.finalKeyword, []);
+    }
+    if (modifiers.staticKeyword != null) {
+      reportError4(ParserErrorCode.STATIC_OPERATOR, modifiers.staticKeyword, []);
+    }
+    if (modifiers.varKeyword != null) {
+      reportError4(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
+    }
+  }
+  /**
+   * Validate that the given set of modifiers is appropriate for a top-level declaration.
+   * @param modifiers the modifiers being validated
+   */
+  void validateModifiersForTopLevelDeclaration(Modifiers modifiers) {
+    if (modifiers.factoryKeyword != null) {
+      reportError4(ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION, modifiers.factoryKeyword, []);
+    }
+    if (modifiers.staticKeyword != null) {
+      reportError4(ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION, modifiers.staticKeyword, []);
+    }
+  }
+  /**
+   * Validate that the given set of modifiers is appropriate for a top-level function.
+   * @param modifiers the modifiers being validated
+   */
+  void validateModifiersForTopLevelFunction(Modifiers modifiers) {
+    validateModifiersForTopLevelDeclaration(modifiers);
+    if (modifiers.abstractKeyword != null) {
+      reportError3(ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION, []);
+    }
+    if (modifiers.constKeyword != null) {
+      reportError4(ParserErrorCode.CONST_CLASS, modifiers.constKeyword, []);
+    }
+    if (modifiers.finalKeyword != null) {
+      reportError4(ParserErrorCode.FINAL_CLASS, modifiers.finalKeyword, []);
+    }
+    if (modifiers.varKeyword != null) {
+      reportError4(ParserErrorCode.VAR_RETURN_TYPE, modifiers.varKeyword, []);
+    }
+  }
+  /**
+   * Validate that the given set of modifiers is appropriate for a field and return the 'final',
+   * 'const' or 'var' keyword if there is one.
+   * @param modifiers the modifiers being validated
+   * @return the 'final', 'const' or 'var' keyword associated with the field
+   */
+  Token validateModifiersForTopLevelVariable(Modifiers modifiers) {
+    validateModifiersForTopLevelDeclaration(modifiers);
+    if (modifiers.abstractKeyword != null) {
+      reportError3(ParserErrorCode.ABSTRACT_TOP_LEVEL_VARIABLE, []);
+    }
+    if (modifiers.externalKeyword != null) {
+      reportError4(ParserErrorCode.EXTERNAL_FIELD, modifiers.externalKeyword, []);
+    }
+    Token constKeyword6 = modifiers.constKeyword;
+    Token finalKeyword4 = modifiers.finalKeyword;
+    Token varKeyword4 = modifiers.varKeyword;
+    if (constKeyword6 != null) {
+      if (finalKeyword4 != null) {
+        reportError4(ParserErrorCode.CONST_AND_FINAL, finalKeyword4, []);
+      }
+      if (varKeyword4 != null) {
+        reportError4(ParserErrorCode.CONST_AND_VAR, varKeyword4, []);
+      }
+    } else if (finalKeyword4 != null) {
+      if (varKeyword4 != null) {
+        reportError4(ParserErrorCode.FINAL_AND_VAR, varKeyword4, []);
+      }
+    }
+    return lexicallyFirst([constKeyword6, finalKeyword4, varKeyword4]);
+  }
+  /**
+   * Validate that the given set of modifiers is appropriate for a class and return the 'abstract'
+   * keyword if there is one.
+   * @param modifiers the modifiers being validated
+   */
+  void validateModifiersForTypedef(Modifiers modifiers) {
+    validateModifiersForTopLevelDeclaration(modifiers);
+    if (modifiers.abstractKeyword != null) {
+      reportError4(ParserErrorCode.ABSTRACT_TYPEDEF, modifiers.abstractKeyword, []);
+    }
+    if (modifiers.constKeyword != null) {
+      reportError4(ParserErrorCode.CONST_TYPEDEF, modifiers.constKeyword, []);
+    }
+    if (modifiers.externalKeyword != null) {
+      reportError4(ParserErrorCode.EXTERNAL_TYPEDEF, modifiers.externalKeyword, []);
+    }
+    if (modifiers.finalKeyword != null) {
+      reportError4(ParserErrorCode.FINAL_TYPEDEF, modifiers.finalKeyword, []);
+    }
+    if (modifiers.varKeyword != null) {
+      reportError4(ParserErrorCode.VAR_TYPEDEF, modifiers.varKeyword, []);
+    }
+  }
+}
+class AnalysisErrorListener_1 implements AnalysisErrorListener {
+  List<bool> errorFound;
+  AnalysisErrorListener_1(this.errorFound);
+  void onError(AnalysisError error) {
+    errorFound[0] = true;
+  }
+}
+/**
+ * The enumeration {@code ParserErrorCode} defines the error codes used for errors detected by the
+ * parser. 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 ParserErrorCode implements ErrorCode {
+  static final ParserErrorCode ABSTRACT_CLASS_MEMBER = new ParserErrorCode.con2('ABSTRACT_CLASS_MEMBER', 0, "Members of classes cannot be declared to be 'abstract'");
+  static final ParserErrorCode ABSTRACT_STATIC_METHOD = new ParserErrorCode.con2('ABSTRACT_STATIC_METHOD', 1, "Static methods cannot be declared to be 'abstract'");
+  static final ParserErrorCode ABSTRACT_TOP_LEVEL_FUNCTION = new ParserErrorCode.con2('ABSTRACT_TOP_LEVEL_FUNCTION', 2, "Top-level functions cannot be declared to be 'abstract'");
+  static final ParserErrorCode ABSTRACT_TOP_LEVEL_VARIABLE = new ParserErrorCode.con2('ABSTRACT_TOP_LEVEL_VARIABLE', 3, "Top-level variables cannot be declared to be 'abstract'");
+  static final ParserErrorCode ABSTRACT_TYPEDEF = new ParserErrorCode.con2('ABSTRACT_TYPEDEF', 4, "Type aliases cannot be declared to be 'abstract'");
+  static final ParserErrorCode BREAK_OUTSIDE_OF_LOOP = new ParserErrorCode.con2('BREAK_OUTSIDE_OF_LOOP', 5, "A break statement cannot be used outside of a loop or switch statement");
+  static final ParserErrorCode BUILT_IN_IDENTIFIER_AS_TYPE_NAME = new ParserErrorCode.con2('BUILT_IN_IDENTIFIER_AS_TYPE_NAME', 6, "The built-in identifier '%s' cannot be used as a type name");
+  static final ParserErrorCode BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME = new ParserErrorCode.con2('BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME', 7, "The built-in identifier '%s' cannot be used as a type alias name");
+  static final ParserErrorCode BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME = new ParserErrorCode.con2('BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME', 8, "The built-in identifier '%s' cannot be used as a type variable name");
+  static final ParserErrorCode CONST_AND_FINAL = new ParserErrorCode.con2('CONST_AND_FINAL', 9, "Members cannot be declared to be both 'const' and 'final'");
+  static final ParserErrorCode CONST_AND_VAR = new ParserErrorCode.con2('CONST_AND_VAR', 10, "Members cannot be declared to be both 'const' and 'var'");
+  static final ParserErrorCode CONST_CLASS = new ParserErrorCode.con2('CONST_CLASS', 11, "Classes cannot be declared to be 'const'");
+  static final ParserErrorCode CONST_METHOD = new ParserErrorCode.con2('CONST_METHOD', 12, "Getters, setters and methods cannot be declared to be 'const'");
+  static final ParserErrorCode CONST_TYPEDEF = new ParserErrorCode.con2('CONST_TYPEDEF', 13, "Type aliases cannot be declared to be 'const'");
+  static final ParserErrorCode CONSTRUCTOR_WITH_RETURN_TYPE = new ParserErrorCode.con2('CONSTRUCTOR_WITH_RETURN_TYPE', 14, "Constructors cannot have a return type");
+  static final ParserErrorCode CONTINUE_OUTSIDE_OF_LOOP = new ParserErrorCode.con2('CONTINUE_OUTSIDE_OF_LOOP', 15, "A continue statement cannot be used outside of a loop or switch statement");
+  static final ParserErrorCode CONTINUE_WITHOUT_LABEL_IN_CASE = new ParserErrorCode.con2('CONTINUE_WITHOUT_LABEL_IN_CASE', 16, "A continue statement in a switch statement must have a label as a target");
+  static final ParserErrorCode DIRECTIVE_AFTER_DECLARATION = new ParserErrorCode.con2('DIRECTIVE_AFTER_DECLARATION', 17, "Directives must appear before any declarations");
+  static final ParserErrorCode DUPLICATE_LABEL_IN_SWITCH_STATEMENT = new ParserErrorCode.con2('DUPLICATE_LABEL_IN_SWITCH_STATEMENT', 18, "The label %s was already used in this switch statement");
+  static final ParserErrorCode DUPLICATED_MODIFIER = new ParserErrorCode.con2('DUPLICATED_MODIFIER', 19, "The modifier '%s' was already specified.");
+  static final ParserErrorCode EXPECTED_CASE_OR_DEFAULT = new ParserErrorCode.con2('EXPECTED_CASE_OR_DEFAULT', 20, "Expected 'case' or 'default'");
+  static final ParserErrorCode EXPECTED_LIST_OR_MAP_LITERAL = new ParserErrorCode.con2('EXPECTED_LIST_OR_MAP_LITERAL', 21, "Expected a list or map literal");
+  static final ParserErrorCode EXPECTED_STRING_LITERAL = new ParserErrorCode.con2('EXPECTED_STRING_LITERAL', 22, "Expected a string literal");
+  static final ParserErrorCode EXPECTED_TOKEN = new ParserErrorCode.con2('EXPECTED_TOKEN', 23, "Expected to find: %s");
+  static final ParserErrorCode EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE = new ParserErrorCode.con2('EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE', 24, "Export directives must preceed part directives");
+  static final ParserErrorCode EXTERNAL_AFTER_CONST = new ParserErrorCode.con2('EXTERNAL_AFTER_CONST', 25, "The modifier 'external' should be before the modifier 'const'");
+  static final ParserErrorCode EXTERNAL_AFTER_FACTORY = new ParserErrorCode.con2('EXTERNAL_AFTER_FACTORY', 26, "The modifier 'external' should be before the modifier 'factory'");
+  static final ParserErrorCode EXTERNAL_AFTER_STATIC = new ParserErrorCode.con2('EXTERNAL_AFTER_STATIC', 27, "The modifier 'external' should be before the modifier 'static'");
+  static final ParserErrorCode EXTERNAL_CLASS = new ParserErrorCode.con2('EXTERNAL_CLASS', 28, "Classes cannot be declared to be 'external'");
+  static final ParserErrorCode EXTERNAL_CONSTRUCTOR_WITH_BODY = new ParserErrorCode.con2('EXTERNAL_CONSTRUCTOR_WITH_BODY', 29, "External constructors cannot have a body");
+  static final ParserErrorCode EXTERNAL_FIELD = new ParserErrorCode.con2('EXTERNAL_FIELD', 30, "Fields cannot be declared to be 'external'");
+  static final ParserErrorCode EXTERNAL_GETTER_WITH_BODY = new ParserErrorCode.con2('EXTERNAL_GETTER_WITH_BODY', 31, "External getters cannot have a body");
+  static final ParserErrorCode EXTERNAL_METHOD_WITH_BODY = new ParserErrorCode.con2('EXTERNAL_METHOD_WITH_BODY', 32, "External methods cannot have a body");
+  static final ParserErrorCode EXTERNAL_OPERATOR_WITH_BODY = new ParserErrorCode.con2('EXTERNAL_OPERATOR_WITH_BODY', 33, "External operators cannot have a body");
+  static final ParserErrorCode EXTERNAL_SETTER_WITH_BODY = new ParserErrorCode.con2('EXTERNAL_SETTER_WITH_BODY', 34, "External setters cannot have a body");
+  static final ParserErrorCode EXTERNAL_TYPEDEF = new ParserErrorCode.con2('EXTERNAL_TYPEDEF', 35, "Type aliases cannot be declared to be 'external'");
+  static final ParserErrorCode FACTORY_TOP_LEVEL_DECLARATION = new ParserErrorCode.con2('FACTORY_TOP_LEVEL_DECLARATION', 36, "Top-level declarations cannot be declared to be 'factory'");
+  static final ParserErrorCode FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR = new ParserErrorCode.con2('FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR', 37, "Field initializers can only be used in a constructor");
+  static final ParserErrorCode FINAL_AND_VAR = new ParserErrorCode.con2('FINAL_AND_VAR', 38, "Members cannot be declared to be both 'final' and 'var'");
+  static final ParserErrorCode FINAL_CLASS = new ParserErrorCode.con2('FINAL_CLASS', 39, "Classes cannot be declared to be 'final'");
+  static final ParserErrorCode FINAL_CONSTRUCTOR = new ParserErrorCode.con2('FINAL_CONSTRUCTOR', 40, "A constructor cannot be declared to be 'final'");
+  static final ParserErrorCode FINAL_METHOD = new ParserErrorCode.con2('FINAL_METHOD', 41, "Getters, setters and methods cannot be declared to be 'final'");
+  static final ParserErrorCode FINAL_TYPEDEF = new ParserErrorCode.con2('FINAL_TYPEDEF', 42, "Type aliases cannot be declared to be 'final'");
+  static final ParserErrorCode GETTER_WITH_PARAMETERS = new ParserErrorCode.con2('GETTER_WITH_PARAMETERS', 43, "Getter should be declared without a parameter list");
+  static final ParserErrorCode ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE = new ParserErrorCode.con2('ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE', 44, "Illegal assignment to non-assignable expression");
+  static final ParserErrorCode IMPLEMENTS_BEFORE_EXTENDS = new ParserErrorCode.con2('IMPLEMENTS_BEFORE_EXTENDS', 45, "The extends clause must be before the implements clause");
+  static final ParserErrorCode IMPLEMENTS_BEFORE_WITH = new ParserErrorCode.con2('IMPLEMENTS_BEFORE_WITH', 46, "The with clause must be before the implements clause");
+  static final ParserErrorCode IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE = new ParserErrorCode.con2('IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE', 47, "Import directives must preceed part directives");
+  static final ParserErrorCode INITIALIZED_VARIABLE_IN_FOR_EACH = new ParserErrorCode.con2('INITIALIZED_VARIABLE_IN_FOR_EACH', 48, "The loop variable in a for-each loop cannot be initialized");
+  static final ParserErrorCode INVALID_CODE_POINT = new ParserErrorCode.con2('INVALID_CODE_POINT', 49, "The escape sequence '%s' is not a valid code point");
+  static final ParserErrorCode INVALID_COMMENT_REFERENCE = new ParserErrorCode.con2('INVALID_COMMENT_REFERENCE', 50, "Comment references should contain a possibly prefixed identifier and can start with 'new', but should not contain anything else");
+  static final ParserErrorCode INVALID_HEX_ESCAPE = new ParserErrorCode.con2('INVALID_HEX_ESCAPE', 51, "An escape sequence starting with '\\x' must be followed by 2 hexidecimal digits");
+  static final ParserErrorCode INVALID_OPERATOR_FOR_SUPER = new ParserErrorCode.con2('INVALID_OPERATOR_FOR_SUPER', 52, "The operator '%s' cannot be used with 'super'");
+  static final ParserErrorCode INVALID_UNICODE_ESCAPE = new ParserErrorCode.con2('INVALID_UNICODE_ESCAPE', 53, "An escape sequence starting with '\\u' must be followed by 4 hexidecimal digits or from 1 to 6 digits between '{' and '}'");
+  static final ParserErrorCode LIBRARY_DIRECTIVE_NOT_FIRST = new ParserErrorCode.con2('LIBRARY_DIRECTIVE_NOT_FIRST', 54, "The library directive must appear before all other directives");
+  static final ParserErrorCode MISSING_ASSIGNABLE_SELECTOR = new ParserErrorCode.con2('MISSING_ASSIGNABLE_SELECTOR', 55, "Missing selector such as \".<identifier>\" or \"[0]\"");
+  static final ParserErrorCode MISSING_CATCH_OR_FINALLY = new ParserErrorCode.con2('MISSING_CATCH_OR_FINALLY', 56, "A try statement must have either a catch or finally clause");
+  static final ParserErrorCode MISSING_CLASS_BODY = new ParserErrorCode.con2('MISSING_CLASS_BODY', 57, "A class definition must have a body, even if it is empty");
+  static final ParserErrorCode MISSING_CONST_FINAL_VAR_OR_TYPE = new ParserErrorCode.con2('MISSING_CONST_FINAL_VAR_OR_TYPE', 58, "Variables must be declared using the keywords 'const', 'final', 'var' or a type name");
+  static final ParserErrorCode MISSING_FUNCTION_BODY = new ParserErrorCode.con2('MISSING_FUNCTION_BODY', 59, "A function body must be provided");
+  static final ParserErrorCode MISSING_FUNCTION_PARAMETERS = new ParserErrorCode.con2('MISSING_FUNCTION_PARAMETERS', 60, "Functions must have an explicit list of parameters");
+  static final ParserErrorCode MISSING_IDENTIFIER = new ParserErrorCode.con2('MISSING_IDENTIFIER', 61, "Expected an identifier");
+  static final ParserErrorCode MISSING_NAME_IN_LIBRARY_DIRECTIVE = new ParserErrorCode.con2('MISSING_NAME_IN_LIBRARY_DIRECTIVE', 62, "Library directives must include a library name");
+  static final ParserErrorCode MISSING_NAME_IN_PART_OF_DIRECTIVE = new ParserErrorCode.con2('MISSING_NAME_IN_PART_OF_DIRECTIVE', 63, "Library directives must include a library name");
+  static final ParserErrorCode MISSING_TYPEDEF_PARAMETERS = new ParserErrorCode.con2('MISSING_TYPEDEF_PARAMETERS', 64, "Type aliases for functions must have an explicit list of parameters");
+  static final ParserErrorCode MISSING_VARIABLE_IN_FOR_EACH = new ParserErrorCode.con2('MISSING_VARIABLE_IN_FOR_EACH', 65, "A loop variable must be declared in a for-each loop before the 'in', but none were found");
+  static final ParserErrorCode MIXED_PARAMETER_GROUPS = new ParserErrorCode.con2('MIXED_PARAMETER_GROUPS', 66, "Cannot have both positional and named parameters in a single parameter list");
+  static final ParserErrorCode MULTIPLE_EXTENDS_CLAUSES = new ParserErrorCode.con2('MULTIPLE_EXTENDS_CLAUSES', 67, "Each class definition can have at most one extends clause");
+  static final ParserErrorCode MULTIPLE_IMPLEMENTS_CLAUSES = new ParserErrorCode.con2('MULTIPLE_IMPLEMENTS_CLAUSES', 68, "Each class definition can have at most one implements clause");
+  static final ParserErrorCode MULTIPLE_LIBRARY_DIRECTIVES = new ParserErrorCode.con2('MULTIPLE_LIBRARY_DIRECTIVES', 69, "Only one library directive may be declared in a file");
+  static final ParserErrorCode MULTIPLE_NAMED_PARAMETER_GROUPS = new ParserErrorCode.con2('MULTIPLE_NAMED_PARAMETER_GROUPS', 70, "Cannot have multiple groups of named parameters in a single parameter list");
+  static final ParserErrorCode MULTIPLE_PART_OF_DIRECTIVES = new ParserErrorCode.con2('MULTIPLE_PART_OF_DIRECTIVES', 71, "Only one part-of directive may be declared in a file");
+  static final ParserErrorCode MULTIPLE_POSITIONAL_PARAMETER_GROUPS = new ParserErrorCode.con2('MULTIPLE_POSITIONAL_PARAMETER_GROUPS', 72, "Cannot have multiple groups of positional parameters in a single parameter list");
+  static final ParserErrorCode MULTIPLE_VARIABLES_IN_FOR_EACH = new ParserErrorCode.con2('MULTIPLE_VARIABLES_IN_FOR_EACH', 73, "A single loop variable must be declared in a for-each loop before the 'in', but %s were found");
+  static final ParserErrorCode MULTIPLE_WITH_CLAUSES = new ParserErrorCode.con2('MULTIPLE_WITH_CLAUSES', 74, "Each class definition can have at most one with clause");
+  static final ParserErrorCode NAMED_PARAMETER_OUTSIDE_GROUP = new ParserErrorCode.con2('NAMED_PARAMETER_OUTSIDE_GROUP', 75, "Named parameters must be enclosed in curly braces ('{' and '}')");
+  static final ParserErrorCode NON_CONSTRUCTOR_FACTORY = new ParserErrorCode.con2('NON_CONSTRUCTOR_FACTORY', 76, "Only constructors can be declared to be a 'factory'");
+  static final ParserErrorCode NON_IDENTIFIER_LIBRARY_NAME = new ParserErrorCode.con2('NON_IDENTIFIER_LIBRARY_NAME', 77, "The name of a library must be an identifier");
+  static final ParserErrorCode NON_PART_OF_DIRECTIVE_IN_PART = new ParserErrorCode.con2('NON_PART_OF_DIRECTIVE_IN_PART', 78, "The part-of directive must be the only directive in a part");
+  static final ParserErrorCode NON_USER_DEFINABLE_OPERATOR = new ParserErrorCode.con2('NON_USER_DEFINABLE_OPERATOR', 79, "The operator '%s' is not user definable");
+  static final ParserErrorCode POSITIONAL_AFTER_NAMED_ARGUMENT = new ParserErrorCode.con2('POSITIONAL_AFTER_NAMED_ARGUMENT', 80, "Positional arguments must occur before named arguments");
+  static final ParserErrorCode POSITIONAL_PARAMETER_OUTSIDE_GROUP = new ParserErrorCode.con2('POSITIONAL_PARAMETER_OUTSIDE_GROUP', 81, "Positional parameters must be enclosed in square brackets ('[' and ']')");
+  static final ParserErrorCode STATIC_AFTER_CONST = new ParserErrorCode.con2('STATIC_AFTER_CONST', 82, "The modifier 'static' should be before the modifier 'const'");
+  static final ParserErrorCode STATIC_AFTER_FINAL = new ParserErrorCode.con2('STATIC_AFTER_FINAL', 83, "The modifier 'static' should be before the modifier 'final'");
+  static final ParserErrorCode STATIC_AFTER_VAR = new ParserErrorCode.con2('STATIC_AFTER_VAR', 84, "The modifier 'static' should be before the modifier 'var'");
+  static final ParserErrorCode STATIC_CONSTRUCTOR = new ParserErrorCode.con2('STATIC_CONSTRUCTOR', 85, "Constructors cannot be static");
+  static final ParserErrorCode STATIC_OPERATOR = new ParserErrorCode.con2('STATIC_OPERATOR', 86, "Operators cannot be static");
+  static final ParserErrorCode STATIC_TOP_LEVEL_DECLARATION = new ParserErrorCode.con2('STATIC_TOP_LEVEL_DECLARATION', 87, "Top-level declarations cannot be declared to be 'static'");
+  static final ParserErrorCode UNEXPECTED_TOKEN = new ParserErrorCode.con2('UNEXPECTED_TOKEN', 88, "Unexpected token '%s'");
+  static final ParserErrorCode USE_OF_UNARY_PLUS_OPERATOR = new ParserErrorCode.con2('USE_OF_UNARY_PLUS_OPERATOR', 89, "There is no unary plus operator in Dart");
+  static final ParserErrorCode WITH_BEFORE_EXTENDS = new ParserErrorCode.con2('WITH_BEFORE_EXTENDS', 90, "The extends clause must be before the with clause");
+  static final ParserErrorCode WITH_WITHOUT_EXTENDS = new ParserErrorCode.con2('WITH_WITHOUT_EXTENDS', 91, "The with clause cannot be used without an extends clause");
+  static final ParserErrorCode WRONG_SEPARATOR_FOR_NAMED_PARAMETER = new ParserErrorCode.con2('WRONG_SEPARATOR_FOR_NAMED_PARAMETER', 92, "The default value of a named parameter should be preceeded by ':'");
+  static final ParserErrorCode WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER = new ParserErrorCode.con2('WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER', 93, "The default value of a positional parameter should be preceeded by '='");
+  static final ParserErrorCode VAR_CLASS = new ParserErrorCode.con2('VAR_CLASS', 94, "Classes cannot be declared to be 'var'");
+  static final ParserErrorCode VAR_RETURN_TYPE = new ParserErrorCode.con2('VAR_RETURN_TYPE', 95, "The return type cannot be 'var'");
+  static final ParserErrorCode VAR_TYPEDEF = new ParserErrorCode.con2('VAR_TYPEDEF', 96, "Type aliases cannot be declared to be 'var'");
+  static final ParserErrorCode VOID_PARAMETER = new ParserErrorCode.con2('VOID_PARAMETER', 97, "Parameters cannot have a type of 'void'");
+  static final ParserErrorCode VOID_VARIABLE = new ParserErrorCode.con2('VOID_VARIABLE', 98, "Variables cannot have a type of 'void'");
+  static final List<ParserErrorCode> values = [ABSTRACT_CLASS_MEMBER, ABSTRACT_STATIC_METHOD, ABSTRACT_TOP_LEVEL_FUNCTION, ABSTRACT_TOP_LEVEL_VARIABLE, ABSTRACT_TYPEDEF, BREAK_OUTSIDE_OF_LOOP, BUILT_IN_IDENTIFIER_AS_TYPE_NAME, BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, CONST_AND_FINAL, CONST_AND_VAR, CONST_CLASS, CONST_METHOD, CONST_TYPEDEF, CONSTRUCTOR_WITH_RETURN_TYPE, CONTINUE_OUTSIDE_OF_LOOP, CONTINUE_WITHOUT_LABEL_IN_CASE, DIRECTIVE_AFTER_DECLARATION, DUPLICATE_LABEL_IN_SWITCH_STATEMENT, DUPLICATED_MODIFIER, EXPECTED_CASE_OR_DEFAULT, EXPECTED_LIST_OR_MAP_LITERAL, EXPECTED_STRING_LITERAL, EXPECTED_TOKEN, EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, EXTERNAL_AFTER_CONST, EXTERNAL_AFTER_FACTORY, EXTERNAL_AFTER_STATIC, EXTERNAL_CLASS, EXTERNAL_CONSTRUCTOR_WITH_BODY, EXTERNAL_FIELD, EXTERNAL_GETTER_WITH_BODY, EXTERNAL_METHOD_WITH_BODY, EXTERNAL_OPERATOR_WITH_BODY, EXTERNAL_SETTER_WITH_BODY, EXTERNAL_TYPEDEF, FACTORY_TOP_LEVEL_DECLARATION, FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, FINAL_AND_VAR, FINAL_CLASS, FINAL_CONSTRUCTOR, FINAL_METHOD, FINAL_TYPEDEF, GETTER_WITH_PARAMETERS, ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, IMPLEMENTS_BEFORE_EXTENDS, IMPLEMENTS_BEFORE_WITH, IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, INITIALIZED_VARIABLE_IN_FOR_EACH, INVALID_CODE_POINT, INVALID_COMMENT_REFERENCE, INVALID_HEX_ESCAPE, INVALID_OPERATOR_FOR_SUPER, INVALID_UNICODE_ESCAPE, LIBRARY_DIRECTIVE_NOT_FIRST, MISSING_ASSIGNABLE_SELECTOR, MISSING_CATCH_OR_FINALLY, MISSING_CLASS_BODY, MISSING_CONST_FINAL_VAR_OR_TYPE, MISSING_FUNCTION_BODY, MISSING_FUNCTION_PARAMETERS, MISSING_IDENTIFIER, MISSING_NAME_IN_LIBRARY_DIRECTIVE, MISSING_NAME_IN_PART_OF_DIRECTIVE, MISSING_TYPEDEF_PARAMETERS, MISSING_VARIABLE_IN_FOR_EACH, MIXED_PARAMETER_GROUPS, MULTIPLE_EXTENDS_CLAUSES, MULTIPLE_IMPLEMENTS_CLAUSES, MULTIPLE_LIBRARY_DIRECTIVES, MULTIPLE_NAMED_PARAMETER_GROUPS, MULTIPLE_PART_OF_DIRECTIVES, MULTIPLE_POSITIONAL_PARAMETER_GROUPS, MULTIPLE_VARIABLES_IN_FOR_EACH, MULTIPLE_WITH_CLAUSES, NAMED_PARAMETER_OUTSIDE_GROUP, NON_CONSTRUCTOR_FACTORY, NON_IDENTIFIER_LIBRARY_NAME, NON_PART_OF_DIRECTIVE_IN_PART, NON_USER_DEFINABLE_OPERATOR, POSITIONAL_AFTER_NAMED_ARGUMENT, POSITIONAL_PARAMETER_OUTSIDE_GROUP, STATIC_AFTER_CONST, STATIC_AFTER_FINAL, STATIC_AFTER_VAR, STATIC_CONSTRUCTOR, STATIC_OPERATOR, STATIC_TOP_LEVEL_DECLARATION, UNEXPECTED_TOKEN, USE_OF_UNARY_PLUS_OPERATOR, WITH_BEFORE_EXTENDS, WITH_WITHOUT_EXTENDS, WRONG_SEPARATOR_FOR_NAMED_PARAMETER, WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER, VAR_CLASS, VAR_RETURN_TYPE, VAR_TYPEDEF, VOID_PARAMETER, VOID_VARIABLE];
+  String __name;
+  int __ordinal = 0;
+  /**
+   * The severity of this error.
+   */
+  ErrorSeverity _severity;
+  /**
+   * 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 severity and message.
+   * @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);
+  }
+  _jtd_constructor_208_impl(String ___name, int ___ordinal, ErrorSeverity severity, String message) {
+    __name = ___name;
+    __ordinal = ___ordinal;
+    this._severity = severity;
+    this._message = message;
+  }
+  /**
+   * 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_209_impl(String ___name, int ___ordinal, String message) {
+    _jtd_constructor_208_impl(___name, ___ordinal, ErrorSeverity.ERROR, message);
+  }
+  ErrorSeverity get errorSeverity => _severity;
+  String get message => _message;
+  ErrorType get type => ErrorType.SYNTACTIC_ERROR;
+  bool needsRecompilation() => true;
+  String toString() => __name;
+}
+/**
+ * Instances of the class {link ToFormattedSourceVisitor} write a source representation of a visited
+ * AST node (and all of it's children) to a writer.
+ */
+class ToFormattedSourceVisitor implements ASTVisitor<Object> {
+  /**
+   * The writer to which the source is to be written.
+   */
+  PrintWriter _writer;
+  int _indentLevel = 0;
+  String _indentString = "";
+  /**
+   * Initialize a newly created visitor to write source code representing the visited nodes to the
+   * given writer.
+   * @param writer the writer to which the source is to be written
+   */
+  ToFormattedSourceVisitor(PrintWriter writer) {
+    this._writer = writer;
+  }
+  Object visitAdjacentStrings(AdjacentStrings node) {
+    visitList5(node.strings, " ");
+    return null;
+  }
+  Object visitAnnotation(Annotation node) {
+    _writer.print('@');
+    visit(node.name);
+    visit7(".", node.constructorName);
+    visit(node.arguments);
+    return null;
+  }
+  Object visitArgumentDefinitionTest(ArgumentDefinitionTest node) {
+    _writer.print('?');
+    visit(node.identifier);
+    return null;
+  }
+  Object visitArgumentList(ArgumentList node) {
+    _writer.print('(');
+    visitList5(node.arguments, ", ");
+    _writer.print(')');
+    return null;
+  }
+  Object visitAsExpression(AsExpression node) {
+    visit(node.expression);
+    _writer.print(" as ");
+    visit(node.type);
+    return null;
+  }
+  Object visitAssertStatement(AssertStatement node) {
+    _writer.print("assert(");
+    visit(node.condition);
+    _writer.print(");");
+    return null;
+  }
+  Object visitAssignmentExpression(AssignmentExpression node) {
+    visit(node.leftHandSide);
+    _writer.print(' ');
+    _writer.print(node.operator.lexeme);
+    _writer.print(' ');
+    visit(node.rightHandSide);
+    return null;
+  }
+  Object visitBinaryExpression(BinaryExpression node) {
+    visit(node.leftOperand);
+    _writer.print(' ');
+    _writer.print(node.operator.lexeme);
+    _writer.print(' ');
+    visit(node.rightOperand);
+    return null;
+  }
+  Object visitBlock(Block node) {
+    _writer.print('{');
+    {
+      indentInc();
+      visitList5(node.statements, "\n");
+      indentDec();
+    }
+    nl2();
+    _writer.print('}');
+    return null;
+  }
+  Object visitBlockFunctionBody(BlockFunctionBody node) {
+    visit(node.block);
+    return null;
+  }
+  Object visitBooleanLiteral(BooleanLiteral node) {
+    _writer.print(node.literal.lexeme);
+    return null;
+  }
+  Object visitBreakStatement(BreakStatement node) {
+    _writer.print("break");
+    visit7(" ", node.label);
+    _writer.print(";");
+    return null;
+  }
+  Object visitCascadeExpression(CascadeExpression node) {
+    visit(node.target);
+    visitList(node.cascadeSections);
+    return null;
+  }
+  Object visitCatchClause(CatchClause node) {
+    visit7("on ", node.exceptionType);
+    if (node.catchKeyword != null) {
+      if (node.exceptionType != null) {
+        _writer.print(' ');
+      }
+      _writer.print("catch (");
+      visit(node.exceptionParameter);
+      visit7(", ", node.stackTraceParameter);
+      _writer.print(") ");
+    } else {
+      _writer.print(" ");
+    }
+    visit(node.body);
+    return null;
+  }
+  Object visitClassDeclaration(ClassDeclaration node) {
+    visit(node.documentationComment);
+    visit8(node.abstractKeyword, " ");
+    _writer.print("class ");
+    visit(node.name);
+    visit(node.typeParameters);
+    visit7(" ", node.extendsClause);
+    visit7(" ", node.withClause);
+    visit7(" ", node.implementsClause);
+    _writer.print(" {");
+    {
+      indentInc();
+      visitList5(node.members, "\n");
+      indentDec();
+    }
+    nl2();
+    _writer.print("}");
+    return null;
+  }
+  Object visitClassTypeAlias(ClassTypeAlias node) {
+    _writer.print("typedef ");
+    visit(node.name);
+    visit(node.typeParameters);
+    _writer.print(" = ");
+    if (node.abstractKeyword != null) {
+      _writer.print("abstract ");
+    }
+    visit(node.superclass);
+    visit7(" ", node.withClause);
+    visit7(" ", node.implementsClause);
+    _writer.print(";");
+    return null;
+  }
+  Object visitComment(Comment node) {
+    Token token = node.beginToken;
+    while (token != null) {
+      bool firstLine = true;
+      for (String line in StringUtils.split(token.lexeme, "\n")) {
+        if (firstLine) {
+          firstLine = false;
+        } else {
+          line = " ${line.trim()}";
+          line = StringUtils.replace(line, "/*", "/ *");
+        }
+        _writer.print(line);
+        nl2();
+      }
+      if (token == node.endToken) {
+        break;
+      }
+    }
+    return null;
+  }
+  Object visitCommentReference(CommentReference node) => null;
+  Object visitCompilationUnit(CompilationUnit node) {
+    ScriptTag scriptTag5 = node.scriptTag;
+    NodeList<Directive> directives4 = node.directives;
+    visit(scriptTag5);
+    String prefix = scriptTag5 == null ? "" : " ";
+    visitList7(prefix, directives4, "\n");
+    prefix = scriptTag5 == null && directives4.isEmpty ? "" : "\n\n";
+    visitList7(prefix, node.declarations, "\n");
+    return null;
+  }
+  Object visitConditionalExpression(ConditionalExpression node) {
+    visit(node.condition);
+    _writer.print(" ? ");
+    visit(node.thenExpression);
+    _writer.print(" : ");
+    visit(node.elseExpression);
+    return null;
+  }
+  Object visitConstructorDeclaration(ConstructorDeclaration node) {
+    visit(node.documentationComment);
+    visit8(node.externalKeyword, " ");
+    visit8(node.constKeyword, " ");
+    visit8(node.factoryKeyword, " ");
+    visit(node.returnType);
+    visit7(".", node.name);
+    visit(node.parameters);
+    visitList7(" : ", node.initializers, ", ");
+    visit7(" = ", node.redirectedConstructor);
+    if (node.body is! EmptyFunctionBody) {
+      _writer.print(' ');
+    }
+    visit(node.body);
+    return null;
+  }
+  Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+    visit8(node.keyword, ".");
+    visit(node.fieldName);
+    _writer.print(" = ");
+    visit(node.expression);
+    return null;
+  }
+  Object visitConstructorName(ConstructorName node) {
+    visit(node.type);
+    visit7(".", node.name);
+    return null;
+  }
+  Object visitContinueStatement(ContinueStatement node) {
+    _writer.print("continue");
+    visit7(" ", node.label);
+    _writer.print(";");
+    return null;
+  }
+  Object visitDefaultFormalParameter(DefaultFormalParameter node) {
+    visit(node.parameter);
+    if (node.separator != null) {
+      _writer.print(" ");
+      _writer.print(node.separator.lexeme);
+      visit7(" ", node.defaultValue);
+    }
+    return null;
+  }
+  Object visitDoStatement(DoStatement node) {
+    _writer.print("do ");
+    visit(node.body);
+    _writer.print(" while (");
+    visit(node.condition);
+    _writer.print(");");
+    return null;
+  }
+  Object visitDoubleLiteral(DoubleLiteral node) {
+    _writer.print(node.literal.lexeme);
+    return null;
+  }
+  Object visitEmptyFunctionBody(EmptyFunctionBody node) {
+    _writer.print(';');
+    return null;
+  }
+  Object visitEmptyStatement(EmptyStatement node) {
+    _writer.print(';');
+    return null;
+  }
+  Object visitExportDirective(ExportDirective node) {
+    _writer.print("export ");
+    visit(node.libraryUri);
+    visitList7(" ", node.combinators, " ");
+    _writer.print(';');
+    return null;
+  }
+  Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    _writer.print("=> ");
+    visit(node.expression);
+    if (node.semicolon != null) {
+      _writer.print(';');
+    }
+    return null;
+  }
+  Object visitExpressionStatement(ExpressionStatement node) {
+    visit(node.expression);
+    _writer.print(';');
+    return null;
+  }
+  Object visitExtendsClause(ExtendsClause node) {
+    _writer.print("extends ");
+    visit(node.superclass);
+    return null;
+  }
+  Object visitFieldDeclaration(FieldDeclaration node) {
+    visit(node.documentationComment);
+    visit8(node.keyword, " ");
+    visit(node.fields);
+    _writer.print(";");
+    return null;
+  }
+  Object visitFieldFormalParameter(FieldFormalParameter node) {
+    visit8(node.keyword, " ");
+    visit6(node.type, " ");
+    _writer.print("this.");
+    visit(node.identifier);
+    return null;
+  }
+  Object visitForEachStatement(ForEachStatement node) {
+    _writer.print("for (");
+    visit(node.loopParameter);
+    _writer.print(" in ");
+    visit(node.iterator);
+    _writer.print(") ");
+    visit(node.body);
+    return null;
+  }
+  Object visitFormalParameterList(FormalParameterList node) {
+    String groupEnd = null;
+    _writer.print('(');
+    NodeList<FormalParameter> parameters11 = node.parameters;
+    int size6 = parameters11.length;
+    for (int i = 0; i < size6; i++) {
+      FormalParameter parameter = parameters11[i];
+      if (i > 0) {
+        _writer.print(", ");
+      }
+      if (groupEnd == null && parameter is DefaultFormalParameter) {
+        if (parameter.kind == ParameterKind.NAMED) {
+          groupEnd = "}";
+          _writer.print('{');
+        } else {
+          groupEnd = "]";
+          _writer.print('[');
+        }
+      }
+      parameter.accept(this);
+    }
+    if (groupEnd != null) {
+      _writer.print(groupEnd);
+    }
+    _writer.print(')');
+    return null;
+  }
+  Object visitForStatement(ForStatement node) {
+    Expression initialization4 = node.initialization;
+    _writer.print("for (");
+    if (initialization4 != null) {
+      visit(initialization4);
+    } else {
+      visit(node.variables);
+    }
+    _writer.print(";");
+    visit7(" ", node.condition);
+    _writer.print(";");
+    visitList7(" ", node.updaters, ", ");
+    _writer.print(") ");
+    visit(node.body);
+    return null;
+  }
+  Object visitFunctionDeclaration(FunctionDeclaration node) {
+    visit6(node.returnType, " ");
+    visit8(node.propertyKeyword, " ");
+    visit(node.name);
+    visit(node.functionExpression);
+    return null;
+  }
+  Object visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
+    visit(node.functionDeclaration);
+    _writer.print(';');
+    return null;
+  }
+  Object visitFunctionExpression(FunctionExpression node) {
+    visit(node.parameters);
+    _writer.print(' ');
+    visit(node.body);
+    return null;
+  }
+  Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    visit(node.function);
+    visit(node.argumentList);
+    return null;
+  }
+  Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+    _writer.print("typedef ");
+    visit6(node.returnType, " ");
+    visit(node.name);
+    visit(node.typeParameters);
+    visit(node.parameters);
+    _writer.print(";");
+    return null;
+  }
+  Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    visit6(node.returnType, " ");
+    visit(node.identifier);
+    visit(node.parameters);
+    return null;
+  }
+  Object visitHideCombinator(HideCombinator node) {
+    _writer.print("hide ");
+    visitList5(node.hiddenNames, ", ");
+    return null;
+  }
+  Object visitIfStatement(IfStatement node) {
+    _writer.print("if (");
+    visit(node.condition);
+    _writer.print(") ");
+    visit(node.thenStatement);
+    visit7(" else ", node.elseStatement);
+    return null;
+  }
+  Object visitImplementsClause(ImplementsClause node) {
+    _writer.print("implements ");
+    visitList5(node.interfaces, ", ");
+    return null;
+  }
+  Object visitImportDirective(ImportDirective node) {
+    _writer.print("import ");
+    visit(node.libraryUri);
+    visit7(" as ", node.prefix);
+    visitList7(" ", node.combinators, " ");
+    _writer.print(';');
+    return null;
+  }
+  Object visitIndexExpression(IndexExpression node) {
+    if (node.isCascaded()) {
+      _writer.print("..");
+    } else {
+      visit(node.array);
+    }
+    _writer.print('[');
+    visit(node.index);
+    _writer.print(']');
+    return null;
+  }
+  Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+    visit8(node.keyword, " ");
+    visit(node.constructorName);
+    visit(node.argumentList);
+    return null;
+  }
+  Object visitIntegerLiteral(IntegerLiteral node) {
+    _writer.print(node.literal.lexeme);
+    return null;
+  }
+  Object visitInterpolationExpression(InterpolationExpression node) {
+    if (node.rightBracket != null) {
+      _writer.print("\${");
+      visit(node.expression);
+      _writer.print("}");
+    } else {
+      _writer.print("\$");
+      visit(node.expression);
+    }
+    return null;
+  }
+  Object visitInterpolationString(InterpolationString node) {
+    _writer.print(node.contents.lexeme);
+    return null;
+  }
+  Object visitIsExpression(IsExpression node) {
+    visit(node.expression);
+    if (node.notOperator == null) {
+      _writer.print(" is ");
+    } else {
+      _writer.print(" is! ");
+    }
+    visit(node.type);
+    return null;
+  }
+  Object visitLabel(Label node) {
+    visit(node.label);
+    _writer.print(":");
+    return null;
+  }
+  Object visitLabeledStatement(LabeledStatement node) {
+    visitList6(node.labels, " ", " ");
+    visit(node.statement);
+    return null;
+  }
+  Object visitLibraryDirective(LibraryDirective node) {
+    _writer.print("library ");
+    visit(node.name);
+    _writer.print(';');
+    nl();
+    return null;
+  }
+  Object visitLibraryIdentifier(LibraryIdentifier node) {
+    _writer.print(node.name);
+    return null;
+  }
+  Object visitListLiteral(ListLiteral node) {
+    if (node.modifier != null) {
+      _writer.print(node.modifier.lexeme);
+      _writer.print(' ');
+    }
+    visit6(node.typeArguments, " ");
+    _writer.print("[");
+    visitList5(node.elements, ", ");
+    _writer.print("]");
+    return null;
+  }
+  Object visitMapLiteral(MapLiteral node) {
+    if (node.modifier != null) {
+      _writer.print(node.modifier.lexeme);
+      _writer.print(' ');
+    }
+    visit6(node.typeArguments, " ");
+    _writer.print("{");
+    visitList5(node.entries, ", ");
+    _writer.print("}");
+    return null;
+  }
+  Object visitMapLiteralEntry(MapLiteralEntry node) {
+    visit(node.key);
+    _writer.print(" : ");
+    visit(node.value);
+    return null;
+  }
+  Object visitMethodDeclaration(MethodDeclaration node) {
+    visit(node.documentationComment);
+    visit8(node.externalKeyword, " ");
+    visit8(node.modifierKeyword, " ");
+    visit6(node.returnType, " ");
+    visit8(node.propertyKeyword, " ");
+    visit8(node.operatorKeyword, " ");
+    visit(node.name);
+    if (!node.isGetter()) {
+      visit(node.parameters);
+    }
+    if (node.body is! EmptyFunctionBody) {
+      _writer.print(' ');
+    }
+    visit(node.body);
+    return null;
+  }
+  Object visitMethodInvocation(MethodInvocation node) {
+    if (node.isCascaded()) {
+      _writer.print("..");
+    } else {
+      visit6(node.target, ".");
+    }
+    visit(node.methodName);
+    visit(node.argumentList);
+    return null;
+  }
+  Object visitNamedExpression(NamedExpression node) {
+    visit(node.name);
+    visit7(" ", node.expression);
+    return null;
+  }
+  Object visitNullLiteral(NullLiteral node) {
+    _writer.print("null");
+    return null;
+  }
+  Object visitParenthesizedExpression(ParenthesizedExpression node) {
+    _writer.print('(');
+    visit(node.expression);
+    _writer.print(')');
+    return null;
+  }
+  Object visitPartDirective(PartDirective node) {
+    _writer.print("part ");
+    visit(node.partUri);
+    _writer.print(';');
+    return null;
+  }
+  Object visitPartOfDirective(PartOfDirective node) {
+    _writer.print("part of ");
+    visit(node.libraryName);
+    _writer.print(';');
+    return null;
+  }
+  Object visitPostfixExpression(PostfixExpression node) {
+    visit(node.operand);
+    _writer.print(node.operator.lexeme);
+    return null;
+  }
+  Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+    visit(node.prefix);
+    _writer.print('.');
+    visit(node.identifier);
+    return null;
+  }
+  Object visitPrefixExpression(PrefixExpression node) {
+    _writer.print(node.operator.lexeme);
+    visit(node.operand);
+    return null;
+  }
+  Object visitPropertyAccess(PropertyAccess node) {
+    if (node.isCascaded()) {
+      _writer.print("..");
+    } else {
+      visit6(node.target, ".");
+    }
+    visit(node.propertyName);
+    return null;
+  }
+  Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
+    _writer.print("this");
+    visit7(".", node.constructorName);
+    visit(node.argumentList);
+    return null;
+  }
+  Object visitReturnStatement(ReturnStatement node) {
+    Expression expression15 = node.expression;
+    if (expression15 == null) {
+      _writer.print("return;");
+    } else {
+      _writer.print("return ");
+      expression15.accept(this);
+      _writer.print(";");
+    }
+    return null;
+  }
+  Object visitScriptTag(ScriptTag node) {
+    _writer.print(node.scriptTag.lexeme);
+    return null;
+  }
+  Object visitShowCombinator(ShowCombinator node) {
+    _writer.print("show ");
+    visitList5(node.shownNames, ", ");
+    return null;
+  }
+  Object visitSimpleFormalParameter(SimpleFormalParameter node) {
+    visit8(node.keyword, " ");
+    visit6(node.type, " ");
+    visit(node.identifier);
+    return null;
+  }
+  Object visitSimpleIdentifier(SimpleIdentifier node) {
+    _writer.print(node.token.lexeme);
+    return null;
+  }
+  Object visitSimpleStringLiteral(SimpleStringLiteral node) {
+    _writer.print(node.literal.lexeme);
+    return null;
+  }
+  Object visitStringInterpolation(StringInterpolation node) {
+    visitList(node.elements);
+    return null;
+  }
+  Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    _writer.print("super");
+    visit7(".", node.constructorName);
+    visit(node.argumentList);
+    return null;
+  }
+  Object visitSuperExpression(SuperExpression node) {
+    _writer.print("super");
+    return null;
+  }
+  Object visitSwitchCase(SwitchCase node) {
+    visitList6(node.labels, " ", " ");
+    _writer.print("case ");
+    visit(node.expression);
+    _writer.print(": ");
+    {
+      indentInc();
+      visitList5(node.statements, "\n");
+      indentDec();
+    }
+    return null;
+  }
+  Object visitSwitchDefault(SwitchDefault node) {
+    visitList6(node.labels, " ", " ");
+    _writer.print("default: ");
+    {
+      indentInc();
+      visitList5(node.statements, "\n");
+      indentDec();
+    }
+    return null;
+  }
+  Object visitSwitchStatement(SwitchStatement node) {
+    _writer.print("switch (");
+    visit(node.expression);
+    _writer.print(") {");
+    {
+      indentInc();
+      visitList5(node.members, "\n");
+      indentDec();
+    }
+    nl2();
+    _writer.print('}');
+    return null;
+  }
+  Object visitThisExpression(ThisExpression node) {
+    _writer.print("this");
+    return null;
+  }
+  Object visitThrowExpression(ThrowExpression node) {
+    _writer.print("throw ");
+    visit(node.expression);
+    return null;
+  }
+  Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    visit6(node.variables, ";");
+    return null;
+  }
+  Object visitTryStatement(TryStatement node) {
+    _writer.print("try ");
+    visit(node.body);
+    visitList7(" ", node.catchClauses, " ");
+    visit7(" finally ", node.finallyClause);
+    return null;
+  }
+  Object visitTypeArgumentList(TypeArgumentList node) {
+    _writer.print('<');
+    visitList5(node.arguments, ", ");
+    _writer.print('>');
+    return null;
+  }
+  Object visitTypeName(TypeName node) {
+    visit(node.name);
+    visit(node.typeArguments);
+    return null;
+  }
+  Object visitTypeParameter(TypeParameter node) {
+    visit(node.name);
+    visit7(" extends ", node.bound);
+    return null;
+  }
+  Object visitTypeParameterList(TypeParameterList node) {
+    _writer.print('<');
+    visitList5(node.typeParameters, ", ");
+    _writer.print('>');
+    return null;
+  }
+  Object visitVariableDeclaration(VariableDeclaration node) {
+    visit(node.name);
+    visit7(" = ", node.initializer);
+    return null;
+  }
+  Object visitVariableDeclarationList(VariableDeclarationList node) {
+    visit8(node.keyword, " ");
+    visit6(node.type, " ");
+    visitList5(node.variables, ", ");
+    return null;
+  }
+  Object visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    visit(node.variables);
+    _writer.print(";");
+    return null;
+  }
+  Object visitWhileStatement(WhileStatement node) {
+    _writer.print("while (");
+    visit(node.condition);
+    _writer.print(") ");
+    visit(node.body);
+    return null;
+  }
+  Object visitWithClause(WithClause node) {
+    _writer.print("with ");
+    visitList5(node.mixinTypes, ", ");
+    return null;
+  }
+  void indent() {
+    _writer.print(_indentString);
+  }
+  void indentDec() {
+    _indentLevel -= 2;
+    _indentString = StringUtils.repeat(" ", _indentLevel);
+  }
+  void indentInc() {
+    _indentLevel += 2;
+    _indentString = StringUtils.repeat(" ", _indentLevel);
+  }
+  void nl() {
+    _writer.print("\n");
+  }
+  void nl2() {
+    nl();
+    indent();
+  }
+  /**
+   * Safely visit the given node.
+   * @param node the node to be visited
+   */
+  void visit(ASTNode node) {
+    if (node != null) {
+      node.accept(this);
+    }
+  }
+  /**
+   * Safely visit the given node, printing the suffix after the node if it is non-<code>null</code>.
+   * @param suffix the suffix to be printed if there is a node to visit
+   * @param node the node to be visited
+   */
+  void visit6(ASTNode node, String suffix) {
+    if (node != null) {
+      node.accept(this);
+      _writer.print(suffix);
+    }
+  }
+  /**
+   * Safely visit the given node, printing the prefix before the node if it is non-<code>null</code>
+   * .
+   * @param prefix the prefix to be printed if there is a node to visit
+   * @param node the node to be visited
+   */
+  void visit7(String prefix, ASTNode node) {
+    if (node != null) {
+      _writer.print(prefix);
+      node.accept(this);
+    }
+  }
+  /**
+   * Safely visit the given node, printing the suffix after the node if it is non-<code>null</code>.
+   * @param suffix the suffix to be printed if there is a node to visit
+   * @param node the node to be visited
+   */
+  void visit8(Token token, String suffix) {
+    if (token != null) {
+      _writer.print(token.lexeme);
+      _writer.print(suffix);
+    }
+  }
+  /**
+   * Print a list of nodes without any separation.
+   * @param nodes the nodes to be printed
+   * @param separator the separator to be printed between adjacent nodes
+   */
+  void visitList(NodeList<ASTNode> nodes) {
+    visitList5(nodes, "");
+  }
+  /**
+   * Print a list of nodes, separated by the given separator.
+   * @param nodes the nodes to be printed
+   * @param separator the separator to be printed between adjacent nodes
+   */
+  void visitList5(NodeList<ASTNode> nodes, String separator) {
+    if (nodes != null) {
+      int size7 = nodes.length;
+      for (int i = 0; i < size7; i++) {
+        if ("\n" == separator) {
+          _writer.print("\n");
+          indent();
+        } else if (i > 0) {
+          _writer.print(separator);
+        }
+        nodes[i].accept(this);
+      }
+    }
+  }
+  /**
+   * Print a list of nodes, separated by the given separator.
+   * @param nodes the nodes to be printed
+   * @param separator the separator to be printed between adjacent nodes
+   * @param suffix the suffix to be printed if the list is not empty
+   */
+  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++) {
+          if (i > 0) {
+            _writer.print(separator);
+          }
+          nodes[i].accept(this);
+        }
+        _writer.print(suffix);
+      }
+    }
+  }
+  /**
+   * Print a list of nodes, separated by the given separator.
+   * @param prefix the prefix to be printed if the list is not empty
+   * @param nodes the nodes to be printed
+   * @param separator the separator to be printed between adjacent nodes
+   */
+  void visitList7(String prefix, NodeList<ASTNode> nodes, String separator) {
+    if (nodes != null) {
+      int size9 = nodes.length;
+      if (size9 > 0) {
+        _writer.print(prefix);
+        for (int i = 0; i < size9; i++) {
+          if (i > 0) {
+            _writer.print(separator);
+          }
+          nodes[i].accept(this);
+        }
+      }
+    }
+  }
+}
\ 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
new file mode 100644
index 0000000..c01e672
--- /dev/null
+++ b/pkg/analyzer-experimental/lib/src/generated/scanner.dart
@@ -0,0 +1,1859 @@
+// 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.scanner;
+
+import 'dart:collection';
+import 'java_core.dart';
+import 'source.dart';
+import 'error.dart';
+import 'instrumentation.dart';
+
+/**
+ * The enumeration {@code Keyword} defines the keywords in the Dart programming language.
+ */
+class Keyword {
+  static final Keyword ASSERT = new Keyword.con1('ASSERT', 0, "assert");
+  static final Keyword BREAK = new Keyword.con1('BREAK', 1, "break");
+  static final Keyword CASE = new Keyword.con1('CASE', 2, "case");
+  static final Keyword CATCH = new Keyword.con1('CATCH', 3, "catch");
+  static final Keyword CLASS = new Keyword.con1('CLASS', 4, "class");
+  static final Keyword CONST = new Keyword.con1('CONST', 5, "const");
+  static final Keyword CONTINUE = new Keyword.con1('CONTINUE', 6, "continue");
+  static final Keyword DEFAULT = new Keyword.con1('DEFAULT', 7, "default");
+  static final Keyword DO = new Keyword.con1('DO', 8, "do");
+  static final Keyword ELSE = new Keyword.con1('ELSE', 9, "else");
+  static final Keyword EXTENDS = new Keyword.con1('EXTENDS', 10, "extends");
+  static final Keyword FALSE = new Keyword.con1('FALSE', 11, "false");
+  static final Keyword FINAL = new Keyword.con1('FINAL', 12, "final");
+  static final Keyword FINALLY = new Keyword.con1('FINALLY', 13, "finally");
+  static final Keyword FOR = new Keyword.con1('FOR', 14, "for");
+  static final Keyword IF = new Keyword.con1('IF', 15, "if");
+  static final Keyword IN = new Keyword.con1('IN', 16, "in");
+  static final Keyword IS = new Keyword.con1('IS', 17, "is");
+  static final Keyword NEW = new Keyword.con1('NEW', 18, "new");
+  static final Keyword NULL = new Keyword.con1('NULL', 19, "null");
+  static final Keyword RETURN = new Keyword.con1('RETURN', 20, "return");
+  static final Keyword SUPER = new Keyword.con1('SUPER', 21, "super");
+  static final Keyword SWITCH = new Keyword.con1('SWITCH', 22, "switch");
+  static final Keyword THIS = new Keyword.con1('THIS', 23, "this");
+  static final Keyword THROW = new Keyword.con1('THROW', 24, "throw");
+  static final Keyword TRUE = new Keyword.con1('TRUE', 25, "true");
+  static final Keyword TRY = new Keyword.con1('TRY', 26, "try");
+  static final Keyword VAR = new Keyword.con1('VAR', 27, "var");
+  static final Keyword VOID = new Keyword.con1('VOID', 28, "void");
+  static final Keyword WHILE = new Keyword.con1('WHILE', 29, "while");
+  static final Keyword WITH = new Keyword.con1('WITH', 30, "with");
+  static final Keyword ABSTRACT = new Keyword.con2('ABSTRACT', 31, "abstract", true);
+  static final Keyword AS = new Keyword.con2('AS', 32, "as", true);
+  static final Keyword DYNAMIC = new Keyword.con2('DYNAMIC', 33, "dynamic", true);
+  static final Keyword EXPORT = new Keyword.con2('EXPORT', 34, "export", true);
+  static final Keyword EXTERNAL = new Keyword.con2('EXTERNAL', 35, "external", true);
+  static final Keyword FACTORY = new Keyword.con2('FACTORY', 36, "factory", true);
+  static final Keyword GET = new Keyword.con2('GET', 37, "get", true);
+  static final Keyword IMPLEMENTS = new Keyword.con2('IMPLEMENTS', 38, "implements", true);
+  static final Keyword IMPORT = new Keyword.con2('IMPORT', 39, "import", true);
+  static final Keyword LIBRARY = new Keyword.con2('LIBRARY', 40, "library", true);
+  static final Keyword OPERATOR = new Keyword.con2('OPERATOR', 41, "operator", true);
+  static final Keyword PART = new Keyword.con2('PART', 42, "part", true);
+  static final Keyword SET = new Keyword.con2('SET', 43, "set", true);
+  static final Keyword STATIC = new Keyword.con2('STATIC', 44, "static", true);
+  static final Keyword TYPEDEF = new Keyword.con2('TYPEDEF', 45, "typedef", true);
+  static final List<Keyword> values = [ASSERT, BREAK, CASE, CATCH, CLASS, CONST, CONTINUE, DEFAULT, DO, ELSE, EXTENDS, FALSE, FINAL, FINALLY, FOR, IF, IN, IS, NEW, NULL, RETURN, SUPER, SWITCH, THIS, THROW, TRUE, TRY, VAR, VOID, WHILE, WITH, ABSTRACT, AS, DYNAMIC, EXPORT, EXTERNAL, FACTORY, GET, IMPLEMENTS, IMPORT, LIBRARY, OPERATOR, PART, SET, STATIC, TYPEDEF];
+  String __name;
+  int __ordinal = 0;
+  /**
+   * The lexeme for the keyword.
+   */
+  String _syntax;
+  /**
+   * A flag indicating whether the keyword is a pseudo-keyword. Pseudo keywords can be used as
+   * identifiers.
+   */
+  bool _isPseudoKeyword2 = false;
+  /**
+   * A table mapping the lexemes of keywords to the corresponding keyword.
+   */
+  static Map<String, Keyword> keywords = createKeywordMap();
+  /**
+   * Create a table mapping the lexemes of keywords to the corresponding keyword.
+   * @return the table that was created
+   */
+  static Map<String, Keyword> createKeywordMap() {
+    LinkedHashMap<String, Keyword> result = new LinkedHashMap<String, Keyword>();
+    for (Keyword keyword in values) {
+      result[keyword._syntax] = keyword;
+    }
+    return result;
+  }
+  /**
+   * Initialize a newly created keyword to have the given syntax. The keyword is not a
+   * pseudo-keyword.
+   * @param syntax the lexeme for the keyword
+   */
+  Keyword.con1(String ___name, int ___ordinal, String syntax) {
+    _jtd_constructor_215_impl(___name, ___ordinal, syntax);
+  }
+  _jtd_constructor_215_impl(String ___name, int ___ordinal, String syntax) {
+    _jtd_constructor_216_impl(___name, ___ordinal, syntax, false);
+  }
+  /**
+   * Initialize a newly created keyword to have the given syntax. The keyword is a pseudo-keyword if
+   * the given flag is {@code true}.
+   * @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);
+  }
+  _jtd_constructor_216_impl(String ___name, int ___ordinal, String syntax, bool isPseudoKeyword) {
+    __name = ___name;
+    __ordinal = ___ordinal;
+    this._syntax = syntax;
+    this._isPseudoKeyword2 = isPseudoKeyword;
+  }
+  /**
+   * Return the lexeme for the keyword.
+   * @return the lexeme for the keyword
+   */
+  String get syntax => _syntax;
+  /**
+   * Return {@code true} if this keyword is a pseudo-keyword. Pseudo keywords can be used as
+   * identifiers.
+   * @return {@code true} if this keyword is a pseudo-keyword
+   */
+  bool isPseudoKeyword() => _isPseudoKeyword2;
+  String toString() => __name;
+}
+/**
+ * Instances of the class {@code CharBufferScanner} implement a scanner that reads from a character
+ * buffer. The scanning logic is in the superclass.
+ */
+class CharBufferScanner extends AbstractScanner {
+  /**
+   * The buffer from which characters will be read.
+   */
+  CharBuffer _buffer;
+  /**
+   * The number of characters in the buffer.
+   */
+  int _bufferLength = 0;
+  /**
+   * The index of the last character that was read.
+   */
+  int _charOffset = 0;
+  /**
+   * Initialize a newly created scanner to scan the characters in the given character buffer.
+   * @param source the source being scanned
+   * @param buffer the buffer from which characters will be read
+   * @param errorListener the error listener that will be informed of any errors that are found
+   */
+  CharBufferScanner(Source source, CharBuffer buffer, AnalysisErrorListener errorListener) : super(source, errorListener) {
+    this._buffer = buffer;
+    this._bufferLength = buffer.length();
+    this._charOffset = -1;
+  }
+  int get offset => _charOffset;
+  int advance() {
+    if (_charOffset + 1 >= _bufferLength) {
+      return -1;
+    }
+    return _buffer.charAt(++_charOffset);
+  }
+  String getString(int start, int endDelta) => _buffer.subSequence(start, _charOffset + 1 + endDelta).toString();
+  int peek() {
+    if (_charOffset + 1 >= _buffer.length()) {
+      return -1;
+    }
+    return _buffer.charAt(_charOffset + 1);
+  }
+}
+/**
+ * Instances of the class {@code TokenWithComment} represent a normal token that is preceded by
+ * comments.
+ */
+class TokenWithComment extends Token {
+  /**
+   * The first comment in the list of comments that precede this token.
+   */
+  Token _precedingComment;
+  /**
+   * Initialize a newly created token to have the given type and offset and to be preceded by the
+   * comments reachable from the given comment.
+   * @param type the type of the token
+   * @param offset the offset from the beginning of the file to the first character in the token
+   * @param precedingComment the first comment in the list of comments that precede this token
+   */
+  TokenWithComment(TokenType type, int offset, Token precedingComment) : super(type, offset) {
+    this._precedingComment = precedingComment;
+  }
+  Token get precedingComments => _precedingComment;
+}
+/**
+ * Instances of the class {@code Token} represent a token that was scanned from the input. Each
+ * token knows which token follows it, acting as the head of a linked list of tokens.
+ */
+class Token {
+  /**
+   * The type of the token.
+   */
+  TokenType _type;
+  /**
+   * The offset from the beginning of the file to the first character in the token.
+   */
+  int _offset = 0;
+  /**
+   * The previous token in the token stream.
+   */
+  Token _previous;
+  /**
+   * The next token in the token stream.
+   */
+  Token _next;
+  /**
+   * Initialize a newly created token to have the given type and offset.
+   * @param type the type of the token
+   * @param offset the offset from the beginning of the file to the first character in the token
+   */
+  Token(TokenType type, int offset) {
+    this._type = type;
+    this._offset = offset;
+  }
+  /**
+   * Return the offset from the beginning of the file to the character after last character of the
+   * token.
+   * @return the offset from the beginning of the file to the first character after last character
+   * of the token
+   */
+  int get end => _offset + length;
+  /**
+   * Return the number of characters in the node's source range.
+   * @return the number of characters in the node's source range
+   */
+  int get length => lexeme.length;
+  /**
+   * Return the lexeme that represents this token.
+   * @return the lexeme that represents this token
+   */
+  String get lexeme => _type.lexeme;
+  /**
+   * Return the next token in the token stream.
+   * @return the next token in the token stream
+   */
+  Token get next => _next;
+  /**
+   * Return the offset from the beginning of the file to the first character in the token.
+   * @return the offset from the beginning of the file to the first character in the token
+   */
+  int get offset => _offset;
+  /**
+   * Return the first comment in the list of comments that precede this token, or {@code null} if
+   * there are no comments preceding this token. Additional comments can be reached by following the
+   * token stream using {@link #getNext()} until {@code null} is returned.
+   * @return the first comment in the list of comments that precede this token
+   */
+  Token get precedingComments => null;
+  /**
+   * Return the previous token in the token stream.
+   * @return the previous token in the token stream
+   */
+  Token get previous => _previous;
+  /**
+   * Return the type of the token.
+   * @return the type of the token
+   */
+  TokenType get type => _type;
+  /**
+   * Return {@code true} if this token represents an operator.
+   * @return {@code true} if this token represents an operator
+   */
+  bool isOperator() => _type.isOperator();
+  /**
+   * Return {@code true} if this token is a synthetic token. A synthetic token is a token that was
+   * introduced by the parser in order to recover from an error in the code. Synthetic tokens always
+   * have a length of zero ({@code 0}).
+   * @return {@code true} if this token is a synthetic token
+   */
+  bool isSynthetic() => length == 0;
+  /**
+   * Return {@code true} if this token represents an operator that can be defined by users.
+   * @return {@code true} if this token represents an operator that can be defined by users
+   */
+  bool isUserDefinableOperator() => _type.isUserDefinableOperator();
+  /**
+   * Set the next token in the token stream to the given token. This has the side-effect of setting
+   * this token to be the previous token for the given token.
+   * @param token the next token in the token stream
+   * @return the token that was passed in
+   */
+  Token setNext(Token token) {
+    _next = token;
+    token.previous2 = this;
+    return token;
+  }
+  /**
+   * Set the next token in the token stream to the given token without changing which token is the
+   * previous token for the given token.
+   * @param token the next token in the token stream
+   * @return the token that was passed in
+   */
+  Token setNextWithoutSettingPrevious(Token token) {
+    _next = token;
+    return token;
+  }
+  /**
+   * Set the offset from the beginning of the file to the first character in the token to the given
+   * 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;
+  }
+  String toString() => lexeme;
+  /**
+   * Return the value of this token. For keyword tokens, this is the keyword associated with the
+   * token, for other tokens it is the lexeme associated with the token.
+   * @return the value of this token
+   */
+  Object value() => _type.lexeme;
+  /**
+   * 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;
+  }
+}
+/**
+ * Instances of the class {@code KeywordToken} represent a keyword in the language.
+ */
+class KeywordToken extends Token {
+  /**
+   * The keyword being represented by this token.
+   */
+  Keyword _keyword;
+  /**
+   * Initialize a newly created token to represent the given keyword.
+   * @param keyword the keyword being represented by this token
+   * @param offset the offset from the beginning of the file to the first character in the token
+   */
+  KeywordToken(Keyword keyword, int offset) : super(TokenType.KEYWORD, offset) {
+    this._keyword = keyword;
+  }
+  /**
+   * Return the keyword being represented by this token.
+   * @return the keyword being represented by this token
+   */
+  Keyword get keyword => _keyword;
+  String get lexeme => _keyword.syntax;
+  Keyword value() => _keyword;
+}
+/**
+ * Instances of the class {@code StringToken} represent a token whose value is independent of it's
+ * type.
+ */
+class StringToken extends Token {
+  /**
+   * The lexeme represented by this token.
+   */
+  String _value2;
+  /**
+   * Initialize a newly created token to represent a token of the given type with the given value.
+   * @param type the type of the token
+   * @param value the lexeme represented by this token
+   * @param offset the offset from the beginning of the file to the first character in the token
+   */
+  StringToken(TokenType type, String value, int offset) : super(type, offset) {
+    this._value2 = value;
+  }
+  String get lexeme => _value2;
+  String value() => _value2;
+}
+/**
+ * The enumeration {@code ScannerErrorCode} defines the error codes used for errors detected by the
+ * scanner.
+ */
+class ScannerErrorCode implements ErrorCode {
+  static final ScannerErrorCode ILLEGAL_CHARACTER = new ScannerErrorCode('ILLEGAL_CHARACTER', 0, "Illegal character %x");
+  static final ScannerErrorCode MISSING_DIGIT = new ScannerErrorCode('MISSING_DIGIT', 1, "Decimal digit expected");
+  static final ScannerErrorCode MISSING_HEX_DIGIT = new ScannerErrorCode('MISSING_HEX_DIGIT', 2, "Hexidecimal digit expected");
+  static final ScannerErrorCode MISSING_QUOTE = new ScannerErrorCode('MISSING_QUOTE', 3, "Expected quote (' or \")");
+  static final ScannerErrorCode UNTERMINATED_MULTI_LINE_COMMENT = new ScannerErrorCode('UNTERMINATED_MULTI_LINE_COMMENT', 4, "Unterminated multi-line comment");
+  static final ScannerErrorCode UNTERMINATED_STRING_LITERAL = new ScannerErrorCode('UNTERMINATED_STRING_LITERAL', 5, "Unterminated string literal");
+  static final List<ScannerErrorCode> values = [ILLEGAL_CHARACTER, MISSING_DIGIT, MISSING_HEX_DIGIT, MISSING_QUOTE, UNTERMINATED_MULTI_LINE_COMMENT, UNTERMINATED_STRING_LITERAL];
+  final String __name;
+  final int __ordinal;
+  /**
+   * 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 message.
+   * @param message the message template used to create the message to be displayed for this error
+   */
+  ScannerErrorCode(this.__name, this.__ordinal, String message) {
+    this._message = message;
+  }
+  ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
+  String get message => _message;
+  ErrorType get type => ErrorType.SYNTACTIC_ERROR;
+  bool needsRecompilation() => true;
+  String toString() => __name;
+}
+/**
+ * Instances of the class {@code BeginTokenWithComment} represent a begin token that is preceded by
+ * comments.
+ */
+class BeginTokenWithComment extends BeginToken {
+  /**
+   * The first comment in the list of comments that precede this token.
+   */
+  Token _precedingComment;
+  /**
+   * Initialize a newly created token to have the given type and offset and to be preceded by the
+   * comments reachable from the given comment.
+   * @param type the type of the token
+   * @param offset the offset from the beginning of the file to the first character in the token
+   * @param precedingComment the first comment in the list of comments that precede this token
+   */
+  BeginTokenWithComment(TokenType type, int offset, Token precedingComment) : super(type, offset) {
+    this._precedingComment = precedingComment;
+  }
+  Token get precedingComments => _precedingComment;
+}
+/**
+ * The enumeration {@code TokenType} defines the types of tokens that can be returned by the
+ * scanner.
+ */
+class TokenType {
+  /**
+   * The type of the token that marks the end of the input.
+   */
+  static final TokenType EOF = new TokenType_EOF('EOF', 0, null, "");
+  static final TokenType DOUBLE = new TokenType.con1('DOUBLE', 1);
+  static final TokenType HEXADECIMAL = new TokenType.con1('HEXADECIMAL', 2);
+  static final TokenType IDENTIFIER = new TokenType.con1('IDENTIFIER', 3);
+  static final TokenType INT = new TokenType.con1('INT', 4);
+  static final TokenType KEYWORD = new TokenType.con1('KEYWORD', 5);
+  static final TokenType MULTI_LINE_COMMENT = new TokenType.con1('MULTI_LINE_COMMENT', 6);
+  static final TokenType SCRIPT_TAG = new TokenType.con1('SCRIPT_TAG', 7);
+  static final TokenType SINGLE_LINE_COMMENT = new TokenType.con1('SINGLE_LINE_COMMENT', 8);
+  static final TokenType STRING = new TokenType.con1('STRING', 9);
+  static final TokenType AMPERSAND = new TokenType.con2('AMPERSAND', 10, TokenClass.BITWISE_AND_OPERATOR, "&");
+  static final TokenType AMPERSAND_AMPERSAND = new TokenType.con2('AMPERSAND_AMPERSAND', 11, TokenClass.LOGICAL_AND_OPERATOR, "&&");
+  static final TokenType AMPERSAND_EQ = new TokenType.con2('AMPERSAND_EQ', 12, TokenClass.ASSIGNMENT_OPERATOR, "&=");
+  static final TokenType AT = new TokenType.con2('AT', 13, null, "@");
+  static final TokenType BANG = new TokenType.con2('BANG', 14, TokenClass.UNARY_PREFIX_OPERATOR, "!");
+  static final TokenType BANG_EQ = new TokenType.con2('BANG_EQ', 15, TokenClass.EQUALITY_OPERATOR, "!=");
+  static final TokenType BAR = new TokenType.con2('BAR', 16, TokenClass.BITWISE_OR_OPERATOR, "|");
+  static final TokenType BAR_BAR = new TokenType.con2('BAR_BAR', 17, TokenClass.LOGICAL_OR_OPERATOR, "||");
+  static final TokenType BAR_EQ = new TokenType.con2('BAR_EQ', 18, TokenClass.ASSIGNMENT_OPERATOR, "|=");
+  static final TokenType COLON = new TokenType.con2('COLON', 19, null, ":");
+  static final TokenType COMMA = new TokenType.con2('COMMA', 20, null, ",");
+  static final TokenType CARET = new TokenType.con2('CARET', 21, TokenClass.BITWISE_XOR_OPERATOR, "^");
+  static final TokenType CARET_EQ = new TokenType.con2('CARET_EQ', 22, TokenClass.ASSIGNMENT_OPERATOR, "^=");
+  static final TokenType CLOSE_CURLY_BRACKET = new TokenType.con2('CLOSE_CURLY_BRACKET', 23, null, "}");
+  static final TokenType CLOSE_PAREN = new TokenType.con2('CLOSE_PAREN', 24, null, ")");
+  static final TokenType CLOSE_SQUARE_BRACKET = new TokenType.con2('CLOSE_SQUARE_BRACKET', 25, null, "]");
+  static final TokenType EQ = new TokenType.con2('EQ', 26, TokenClass.ASSIGNMENT_OPERATOR, "=");
+  static final TokenType EQ_EQ = new TokenType.con2('EQ_EQ', 27, TokenClass.EQUALITY_OPERATOR, "==");
+  static final TokenType FUNCTION = new TokenType.con2('FUNCTION', 28, null, "=>");
+  static final TokenType GT = new TokenType.con2('GT', 29, TokenClass.RELATIONAL_OPERATOR, ">");
+  static final TokenType GT_EQ = new TokenType.con2('GT_EQ', 30, TokenClass.RELATIONAL_OPERATOR, ">=");
+  static final TokenType GT_GT = new TokenType.con2('GT_GT', 31, TokenClass.SHIFT_OPERATOR, ">>");
+  static final TokenType GT_GT_EQ = new TokenType.con2('GT_GT_EQ', 32, TokenClass.ASSIGNMENT_OPERATOR, ">>=");
+  static final TokenType HASH = new TokenType.con2('HASH', 33, null, "#");
+  static final TokenType INDEX = new TokenType.con2('INDEX', 34, TokenClass.UNARY_POSTFIX_OPERATOR, "[]");
+  static final TokenType INDEX_EQ = new TokenType.con2('INDEX_EQ', 35, TokenClass.UNARY_POSTFIX_OPERATOR, "[]=");
+  static final TokenType IS = new TokenType.con2('IS', 36, TokenClass.RELATIONAL_OPERATOR, "is");
+  static final TokenType LT = new TokenType.con2('LT', 37, TokenClass.RELATIONAL_OPERATOR, "<");
+  static final TokenType LT_EQ = new TokenType.con2('LT_EQ', 38, TokenClass.RELATIONAL_OPERATOR, "<=");
+  static final TokenType LT_LT = new TokenType.con2('LT_LT', 39, TokenClass.SHIFT_OPERATOR, "<<");
+  static final TokenType LT_LT_EQ = new TokenType.con2('LT_LT_EQ', 40, TokenClass.ASSIGNMENT_OPERATOR, "<<=");
+  static final TokenType MINUS = new TokenType.con2('MINUS', 41, TokenClass.ADDITIVE_OPERATOR, "-");
+  static final TokenType MINUS_EQ = new TokenType.con2('MINUS_EQ', 42, TokenClass.ASSIGNMENT_OPERATOR, "-=");
+  static final TokenType MINUS_MINUS = new TokenType.con2('MINUS_MINUS', 43, TokenClass.UNARY_PREFIX_OPERATOR, "--");
+  static final TokenType OPEN_CURLY_BRACKET = new TokenType.con2('OPEN_CURLY_BRACKET', 44, null, "{");
+  static final TokenType OPEN_PAREN = new TokenType.con2('OPEN_PAREN', 45, TokenClass.UNARY_POSTFIX_OPERATOR, "(");
+  static final TokenType OPEN_SQUARE_BRACKET = new TokenType.con2('OPEN_SQUARE_BRACKET', 46, TokenClass.UNARY_POSTFIX_OPERATOR, "[");
+  static final TokenType PERCENT = new TokenType.con2('PERCENT', 47, TokenClass.MULTIPLICATIVE_OPERATOR, "%");
+  static final TokenType PERCENT_EQ = new TokenType.con2('PERCENT_EQ', 48, TokenClass.ASSIGNMENT_OPERATOR, "%=");
+  static final TokenType PERIOD = new TokenType.con2('PERIOD', 49, TokenClass.UNARY_POSTFIX_OPERATOR, ".");
+  static final TokenType PERIOD_PERIOD = new TokenType.con2('PERIOD_PERIOD', 50, TokenClass.CASCADE_OPERATOR, "..");
+  static final TokenType PLUS = new TokenType.con2('PLUS', 51, TokenClass.ADDITIVE_OPERATOR, "+");
+  static final TokenType PLUS_EQ = new TokenType.con2('PLUS_EQ', 52, TokenClass.ASSIGNMENT_OPERATOR, "+=");
+  static final TokenType PLUS_PLUS = new TokenType.con2('PLUS_PLUS', 53, TokenClass.UNARY_PREFIX_OPERATOR, "++");
+  static final TokenType QUESTION = new TokenType.con2('QUESTION', 54, TokenClass.CONDITIONAL_OPERATOR, "?");
+  static final TokenType SEMICOLON = new TokenType.con2('SEMICOLON', 55, null, ";");
+  static final TokenType SLASH = new TokenType.con2('SLASH', 56, TokenClass.MULTIPLICATIVE_OPERATOR, "/");
+  static final TokenType SLASH_EQ = new TokenType.con2('SLASH_EQ', 57, TokenClass.ASSIGNMENT_OPERATOR, "/=");
+  static final TokenType STAR = new TokenType.con2('STAR', 58, TokenClass.MULTIPLICATIVE_OPERATOR, "*");
+  static final TokenType STAR_EQ = new TokenType.con2('STAR_EQ', 59, TokenClass.ASSIGNMENT_OPERATOR, "*=");
+  static final TokenType STRING_INTERPOLATION_EXPRESSION = new TokenType.con2('STRING_INTERPOLATION_EXPRESSION', 60, null, "\${");
+  static final TokenType STRING_INTERPOLATION_IDENTIFIER = new TokenType.con2('STRING_INTERPOLATION_IDENTIFIER', 61, null, "\$");
+  static final TokenType TILDE = new TokenType.con2('TILDE', 62, TokenClass.UNARY_PREFIX_OPERATOR, "~");
+  static final TokenType TILDE_SLASH = new TokenType.con2('TILDE_SLASH', 63, TokenClass.MULTIPLICATIVE_OPERATOR, "~/");
+  static final TokenType TILDE_SLASH_EQ = new TokenType.con2('TILDE_SLASH_EQ', 64, TokenClass.ASSIGNMENT_OPERATOR, "~/=");
+  static final TokenType BACKPING = new TokenType.con2('BACKPING', 65, null, "`");
+  static final TokenType BACKSLASH = new TokenType.con2('BACKSLASH', 66, null, "\\");
+  static final TokenType PERIOD_PERIOD_PERIOD = new TokenType.con2('PERIOD_PERIOD_PERIOD', 67, null, "...");
+  static final List<TokenType> values = [EOF, DOUBLE, HEXADECIMAL, IDENTIFIER, INT, KEYWORD, MULTI_LINE_COMMENT, SCRIPT_TAG, SINGLE_LINE_COMMENT, STRING, AMPERSAND, AMPERSAND_AMPERSAND, AMPERSAND_EQ, AT, BANG, BANG_EQ, BAR, BAR_BAR, BAR_EQ, COLON, COMMA, CARET, CARET_EQ, CLOSE_CURLY_BRACKET, CLOSE_PAREN, CLOSE_SQUARE_BRACKET, EQ, EQ_EQ, FUNCTION, GT, GT_EQ, GT_GT, GT_GT_EQ, HASH, INDEX, INDEX_EQ, IS, LT, LT_EQ, LT_LT, LT_LT_EQ, MINUS, MINUS_EQ, MINUS_MINUS, OPEN_CURLY_BRACKET, OPEN_PAREN, OPEN_SQUARE_BRACKET, PERCENT, PERCENT_EQ, PERIOD, PERIOD_PERIOD, PLUS, PLUS_EQ, PLUS_PLUS, QUESTION, SEMICOLON, SLASH, SLASH_EQ, STAR, STAR_EQ, STRING_INTERPOLATION_EXPRESSION, STRING_INTERPOLATION_IDENTIFIER, TILDE, TILDE_SLASH, TILDE_SLASH_EQ, BACKPING, BACKSLASH, PERIOD_PERIOD_PERIOD];
+  String __name;
+  int __ordinal = 0;
+  /**
+   * The class of the token.
+   */
+  TokenClass _tokenClass;
+  /**
+   * The lexeme that defines this type of token, or {@code null} if there is more than one possible
+   * lexeme for this type of token.
+   */
+  String _lexeme;
+  TokenType.con1(String ___name, int ___ordinal) {
+    _jtd_constructor_227_impl(___name, ___ordinal);
+  }
+  _jtd_constructor_227_impl(String ___name, int ___ordinal) {
+    _jtd_constructor_228_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);
+  }
+  _jtd_constructor_228_impl(String ___name, int ___ordinal, TokenClass tokenClass, String lexeme) {
+    __name = ___name;
+    __ordinal = ___ordinal;
+    this._tokenClass = tokenClass == null ? TokenClass.NO_CLASS : tokenClass;
+    this._lexeme = lexeme;
+  }
+  /**
+   * Return the lexeme that defines this type of token, or {@code null} if there is more than one
+   * possible lexeme for this type of token.
+   * @return the lexeme that defines this type of token
+   */
+  String get lexeme => _lexeme;
+  /**
+   * Return the precedence of the token, or {@code 0} if the token does not represent an operator.
+   * @return the precedence of the token
+   */
+  int get precedence => _tokenClass.precedence;
+  /**
+   * 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;
+  /**
+   * 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;
+  /**
+   * 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;
+  /**
+   * 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 == "--";
+  /**
+   * 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;
+  /**
+   * 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;
+  /**
+   * 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;
+  /**
+   * 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;
+  /**
+   * 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;
+  /**
+   * 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;
+  /**
+   * 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 == "|";
+  String toString() => __name;
+}
+class TokenType_EOF extends TokenType {
+  TokenType_EOF(String ___name, int ___ordinal, TokenClass arg0, String arg1) : super.con2(___name, ___ordinal, arg0, arg1);
+  String toString() => "-eof-";
+}
+/**
+ * Instances of the class {@code TokenWithComment} represent a string token that is preceded by
+ * comments.
+ */
+class StringTokenWithComment extends StringToken {
+  /**
+   * The first comment in the list of comments that precede this token.
+   */
+  Token _precedingComment;
+  /**
+   * Initialize a newly created token to have the given type and offset and to be preceded by the
+   * comments reachable from the given comment.
+   * @param type the type of the token
+   * @param offset the offset from the beginning of the file to the first character in the token
+   * @param precedingComment the first comment in the list of comments that precede this token
+   */
+  StringTokenWithComment(TokenType type, String value, int offset, Token precedingComment) : super(type, value, offset) {
+    this._precedingComment = precedingComment;
+  }
+  Token get precedingComments => _precedingComment;
+}
+/**
+ * Instances of the class {@code BeginToken} represent the opening half of a grouping pair of
+ * tokens. This is used for curly brackets ('{'), parentheses ('('), and square brackets ('[').
+ */
+class BeginToken extends Token {
+  /**
+   * The token that corresponds to this token.
+   */
+  Token _endToken;
+  /**
+   * Initialize a newly created token representing the opening half of a grouping pair of tokens.
+   * @param type the type of the token
+   * @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));
+  }
+  /**
+   * Return the token that corresponds to this token.
+   * @return the token that corresponds to this token
+   */
+  Token get endToken => _endToken;
+  /**
+   * 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) {
+    this._endToken = token;
+  }
+}
+/**
+ * The enumeration {@code TokenClass} represents classes (or groups) of tokens with a similar use.
+ */
+class TokenClass {
+  /**
+   * A value used to indicate that the token type is not part of any specific class of token.
+   */
+  static final TokenClass NO_CLASS = new TokenClass.con1('NO_CLASS', 0);
+  /**
+   * A value used to indicate that the token type is an additive operator.
+   */
+  static final TokenClass ADDITIVE_OPERATOR = new TokenClass.con2('ADDITIVE_OPERATOR', 1, 12);
+  /**
+   * A value used to indicate that the token type is an assignment operator.
+   */
+  static final TokenClass ASSIGNMENT_OPERATOR = new TokenClass.con2('ASSIGNMENT_OPERATOR', 2, 1);
+  /**
+   * A value used to indicate that the token type is a bitwise-and operator.
+   */
+  static final TokenClass BITWISE_AND_OPERATOR = new TokenClass.con2('BITWISE_AND_OPERATOR', 3, 8);
+  /**
+   * A value used to indicate that the token type is a bitwise-or operator.
+   */
+  static final TokenClass BITWISE_OR_OPERATOR = new TokenClass.con2('BITWISE_OR_OPERATOR', 4, 6);
+  /**
+   * A value used to indicate that the token type is a bitwise-xor operator.
+   */
+  static final TokenClass BITWISE_XOR_OPERATOR = new TokenClass.con2('BITWISE_XOR_OPERATOR', 5, 7);
+  /**
+   * A value used to indicate that the token type is a cascade operator.
+   */
+  static final TokenClass CASCADE_OPERATOR = new TokenClass.con2('CASCADE_OPERATOR', 6, 2);
+  /**
+   * A value used to indicate that the token type is a conditional operator.
+   */
+  static final TokenClass CONDITIONAL_OPERATOR = new TokenClass.con2('CONDITIONAL_OPERATOR', 7, 3);
+  /**
+   * A value used to indicate that the token type is an equality operator.
+   */
+  static final TokenClass EQUALITY_OPERATOR = new TokenClass.con2('EQUALITY_OPERATOR', 8, 9);
+  /**
+   * A value used to indicate that the token type is a logical-and operator.
+   */
+  static final TokenClass LOGICAL_AND_OPERATOR = new TokenClass.con2('LOGICAL_AND_OPERATOR', 9, 5);
+  /**
+   * A value used to indicate that the token type is a logical-or operator.
+   */
+  static final TokenClass LOGICAL_OR_OPERATOR = new TokenClass.con2('LOGICAL_OR_OPERATOR', 10, 4);
+  /**
+   * A value used to indicate that the token type is a multiplicative operator.
+   */
+  static final TokenClass MULTIPLICATIVE_OPERATOR = new TokenClass.con2('MULTIPLICATIVE_OPERATOR', 11, 13);
+  /**
+   * A value used to indicate that the token type is a relational operator.
+   */
+  static final TokenClass RELATIONAL_OPERATOR = new TokenClass.con2('RELATIONAL_OPERATOR', 12, 10);
+  /**
+   * A value used to indicate that the token type is a shift operator.
+   */
+  static final TokenClass SHIFT_OPERATOR = new TokenClass.con2('SHIFT_OPERATOR', 13, 11);
+  /**
+   * A value used to indicate that the token type is a unary operator.
+   */
+  static final TokenClass UNARY_POSTFIX_OPERATOR = new TokenClass.con2('UNARY_POSTFIX_OPERATOR', 14, 15);
+  /**
+   * A value used to indicate that the token type is a unary operator.
+   */
+  static final TokenClass UNARY_PREFIX_OPERATOR = new TokenClass.con2('UNARY_PREFIX_OPERATOR', 15, 14);
+  static final List<TokenClass> values = [NO_CLASS, ADDITIVE_OPERATOR, ASSIGNMENT_OPERATOR, BITWISE_AND_OPERATOR, BITWISE_OR_OPERATOR, BITWISE_XOR_OPERATOR, CASCADE_OPERATOR, CONDITIONAL_OPERATOR, EQUALITY_OPERATOR, LOGICAL_AND_OPERATOR, LOGICAL_OR_OPERATOR, MULTIPLICATIVE_OPERATOR, RELATIONAL_OPERATOR, SHIFT_OPERATOR, UNARY_POSTFIX_OPERATOR, UNARY_PREFIX_OPERATOR];
+  String __name;
+  int __ordinal = 0;
+  /**
+   * The precedence of tokens of this class, or {@code 0} if the such tokens do not represent an
+   * operator.
+   */
+  int _precedence = 0;
+  TokenClass.con1(String ___name, int ___ordinal) {
+    _jtd_constructor_225_impl(___name, ___ordinal);
+  }
+  _jtd_constructor_225_impl(String ___name, int ___ordinal) {
+    _jtd_constructor_226_impl(___name, ___ordinal, 0);
+  }
+  TokenClass.con2(String ___name, int ___ordinal, int precedence) {
+    _jtd_constructor_226_impl(___name, ___ordinal, precedence);
+  }
+  _jtd_constructor_226_impl(String ___name, int ___ordinal, int precedence) {
+    __name = ___name;
+    __ordinal = ___ordinal;
+    this._precedence = precedence;
+  }
+  /**
+   * Return the precedence of tokens of this class, or {@code 0} if the such tokens do not represent
+   * an operator.
+   * @return the precedence of tokens of this class
+   */
+  int get precedence => _precedence;
+  String toString() => __name;
+}
+/**
+ * Instances of the class {@code StringScanner} implement a scanner that reads from a string. The
+ * scanning logic is in the superclass.
+ */
+class StringScanner extends AbstractScanner {
+  /**
+   * The offset from the beginning of the file to the beginning of the source being scanned.
+   */
+  int _offsetDelta = 0;
+  /**
+   * The string from which characters will be read.
+   */
+  String _string;
+  /**
+   * The number of characters in the string.
+   */
+  int _stringLength = 0;
+  /**
+   * The index, relative to the string, of the last character that was read.
+   */
+  int _charOffset = 0;
+  /**
+   * Initialize a newly created scanner to scan the characters in the given string.
+   * @param source the source being scanned
+   * @param string the string from which characters will be read
+   * @param errorListener the error listener that will be informed of any errors that are found
+   */
+  StringScanner(Source source, String string, AnalysisErrorListener errorListener) : super(source, errorListener) {
+    this._offsetDelta = 0;
+    this._string = string;
+    this._stringLength = string.length;
+    this._charOffset = -1;
+  }
+  int get offset => _offsetDelta + _charOffset;
+  /**
+   * Record that the source begins on the given line and column at the given offset. The line starts
+   * for lines before the given line will not be correct.
+   * <p>
+   * This method must be invoked at most one time and must be invoked before scanning begins. The
+   * values provided must be sensible. The results are undefined if these conditions are violated.
+   * @param line the one-based index of the line containing the first character of the source
+   * @param column the one-based index of the column in which the first character of the source
+   * occurs
+   * @param offset the zero-based offset from the beginning of the larger context to the first
+   * character of the source
+   */
+  void setSourceStart(int line, int column, int offset) {
+    if (line < 1 || column < 1 || offset < 0 || (line + column - 2) >= offset) {
+      return;
+    }
+    _offsetDelta = 1;
+    for (int i = 2; i < line; i++) {
+      recordStartOfLine();
+    }
+    _offsetDelta = offset - column + 1;
+    recordStartOfLine();
+    _offsetDelta = offset;
+  }
+  int advance() {
+    if (_charOffset + 1 >= _stringLength) {
+      return -1;
+    }
+    return _string.charCodeAt(++_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);
+  }
+}
+/**
+ * The abstract class {@code AbstractScanner} implements a scanner for Dart code. Subclasses are
+ * required to implement the interface used to access the characters being scanned.
+ * <p>
+ * The lexical structure of Dart is ambiguous without knowledge of the context in which a token is
+ * being scanned. For example, without context we cannot determine whether source of the form "<<"
+ * should be scanned as a single left-shift operator or as two left angle brackets. This scanner
+ * does not have any context, so it always resolves such conflicts by scanning the longest possible
+ * token.
+ */
+abstract class AbstractScanner {
+  /**
+   * The source being scanned.
+   */
+  Source _source;
+  /**
+   * The error listener that will be informed of any errors that are found during the scan.
+   */
+  AnalysisErrorListener _errorListener;
+  /**
+   * The token pointing to the head of the linked list of tokens.
+   */
+  Token _tokens;
+  /**
+   * The last token that was scanned.
+   */
+  Token _tail;
+  /**
+   * The first token in the list of comment tokens found since the last non-comment token.
+   */
+  Token _firstComment;
+  /**
+   * The last token in the list of comment tokens found since the last non-comment token.
+   */
+  Token _lastComment;
+  /**
+   * The index of the first character of the current token.
+   */
+  int _tokenStart = 0;
+  /**
+   * A list containing the offsets of the first character of each line in the source code.
+   */
+  List<int> _lineStarts = new List<int>();
+  /**
+   * A list, treated something like a stack, of tokens representing the beginning of a matched pair.
+   * It is used to pair the end tokens with the begin tokens.
+   */
+  List<BeginToken> _groupingStack = new List<BeginToken>();
+  /**
+   * A flag indicating whether any unmatched groups were found during the parse.
+   */
+  bool _hasUnmatchedGroups2 = false;
+  /**
+   * A non-breaking space, which is allowed by this scanner as a white-space character.
+   */
+  static int _$NBSP = 160;
+  /**
+   * Initialize a newly created scanner.
+   * @param source the source being scanned
+   * @param errorListener the error listener that will be informed of any errors that are found
+   */
+  AbstractScanner(Source source, AnalysisErrorListener errorListener) {
+    this._source = source;
+    this._errorListener = errorListener;
+    _tokens = new Token(TokenType.EOF, -1);
+    _tokens.setNext(_tokens);
+    _tail = _tokens;
+    _tokenStart = -1;
+    _lineStarts.add(0);
+  }
+  /**
+   * Return an array containing the offsets of the first character of each line in the source code.
+   * @return an array containing the offsets of the first character of each line in the source code
+   */
+  List<int> get lineStarts => _lineStarts;
+  /**
+   * Return the current offset relative to the beginning of the file. Return the initial offset if
+   * the scanner has not yet scanned the source code, and one (1) past the end of the source code if
+   * the source code has been scanned.
+   * @return the current offset of the scanner in the source
+   */
+  int get offset;
+  /**
+   * Return {@code true} if any unmatched groups were found during the parse.
+   * @return {@code true} if any unmatched groups were found during the parse
+   */
+  bool hasUnmatchedGroups() => _hasUnmatchedGroups2;
+  /**
+   * Scan the source code to produce a list of tokens representing the source.
+   * @return the first token in the list of tokens that were produced
+   */
+  Token tokenize() {
+    int startTime = System.currentTimeMillis();
+    int next = advance();
+    while (next != -1) {
+      next = bigSwitch(next);
+    }
+    appendEofToken();
+    int endTime = System.currentTimeMillis();
+    Instrumentation.metric2("Engine-Scanner", endTime - startTime).with3("chars", offset).log();
+    return firstToken();
+  }
+  /**
+   * Advance the current position and return the character at the new current position.
+   * @return the character at the new current position
+   */
+  int advance();
+  /**
+   * Return the substring of the source code between the start offset and the modified current
+   * position. The current position is modified by adding the end delta.
+   * @param start the offset to the beginning of the string, relative to the start of the file
+   * @param endDelta the number of character after the current location to be included in the
+   * string, or the number of characters before the current location to be excluded if the
+   * offset is negative
+   * @return the specified substring of the source code
+   */
+  String getString(int start, int endDelta);
+  /**
+   * Return the character at the current position without changing the current position.
+   * @return the character at the current position
+   */
+  int peek();
+  /**
+   * Record the fact that we are at the beginning of a new line in the source.
+   */
+  void recordStartOfLine() {
+    _lineStarts.add(offset);
+  }
+  void appendBeginToken(TokenType type) {
+    BeginToken token;
+    if (_firstComment == null) {
+      token = new BeginToken(type, _tokenStart);
+    } else {
+      token = new BeginTokenWithComment(type, _tokenStart, _firstComment);
+      _firstComment = null;
+      _lastComment = null;
+    }
+    _tail = _tail.setNext(token);
+    _groupingStack.add(token);
+  }
+  void appendCommentToken(TokenType type, String value) {
+    if (_firstComment == null) {
+      _firstComment = new StringToken(type, value, _tokenStart);
+      _lastComment = _firstComment;
+    } else {
+      _lastComment = _lastComment.setNext(new StringToken(type, value, _tokenStart));
+    }
+  }
+  void appendEndToken(TokenType type, TokenType beginType) {
+    Token token;
+    if (_firstComment == null) {
+      token = new Token(type, _tokenStart);
+    } else {
+      token = new TokenWithComment(type, _tokenStart, _firstComment);
+      _firstComment = null;
+      _lastComment = null;
+    }
+    _tail = _tail.setNext(token);
+    int last = _groupingStack.length - 1;
+    if (last >= 0) {
+      BeginToken begin = _groupingStack[last];
+      if (begin.type == beginType) {
+        begin.endToken2 = token;
+        _groupingStack.removeAt(last);
+      }
+    }
+  }
+  void appendEofToken() {
+    Token eofToken;
+    if (_firstComment == null) {
+      eofToken = new Token(TokenType.EOF, offset + 1);
+    } else {
+      eofToken = new TokenWithComment(TokenType.EOF, offset + 1, _firstComment);
+      _firstComment = null;
+      _lastComment = null;
+    }
+    eofToken.setNext(eofToken);
+    _tail = _tail.setNext(eofToken);
+    if (!_groupingStack.isEmpty) {
+      _hasUnmatchedGroups2 = true;
+    }
+  }
+  void appendKeywordToken(Keyword keyword) {
+    if (_firstComment == null) {
+      _tail = _tail.setNext(new KeywordToken(keyword, _tokenStart));
+    } else {
+      _tail = _tail.setNext(new KeywordTokenWithComment(keyword, _tokenStart, _firstComment));
+      _firstComment = null;
+      _lastComment = null;
+    }
+  }
+  void appendStringToken(TokenType type, String value) {
+    if (_firstComment == null) {
+      _tail = _tail.setNext(new StringToken(type, value, _tokenStart));
+    } else {
+      _tail = _tail.setNext(new StringTokenWithComment(type, value, _tokenStart, _firstComment));
+      _firstComment = null;
+      _lastComment = null;
+    }
+  }
+  void appendStringToken2(TokenType type, String value, int offset) {
+    if (_firstComment == null) {
+      _tail = _tail.setNext(new StringToken(type, value, _tokenStart + offset));
+    } else {
+      _tail = _tail.setNext(new StringTokenWithComment(type, value, _tokenStart + offset, _firstComment));
+      _firstComment = null;
+      _lastComment = null;
+    }
+  }
+  void appendToken(TokenType type) {
+    if (_firstComment == null) {
+      _tail = _tail.setNext(new Token(type, _tokenStart));
+    } else {
+      _tail = _tail.setNext(new TokenWithComment(type, _tokenStart, _firstComment));
+      _firstComment = null;
+      _lastComment = null;
+    }
+  }
+  void appendToken2(TokenType type, int offset) {
+    if (_firstComment == null) {
+      _tail = _tail.setNext(new Token(type, offset));
+    } else {
+      _tail = _tail.setNext(new TokenWithComment(type, offset, _firstComment));
+      _firstComment = null;
+      _lastComment = null;
+    }
+  }
+  void beginToken() {
+    _tokenStart = offset;
+  }
+  int bigSwitch(int next) {
+    beginToken();
+    if (next == 0xd) {
+      next = advance();
+      if (next == 0xa) {
+        next = advance();
+      }
+      recordStartOfLine();
+      return next;
+    } else if (next == 0xa) {
+      recordStartOfLine();
+      return advance();
+    } else if (next == 0x9 || next == 0x20) {
+      return advance();
+    }
+    if (next == 0x72) {
+      int peek3 = peek();
+      if (peek3 == 0x22 || peek3 == 0x27) {
+        int start = offset;
+        return tokenizeString(advance(), start, true);
+      }
+    }
+    if (0x61 <= next && next <= 0x7a) {
+      return tokenizeKeywordOrIdentifier(next, true);
+    }
+    if ((0x41 <= next && next <= 0x5a) || next == 0x5f || next == 0x24) {
+      return tokenizeIdentifier(next, offset, true);
+    }
+    if (next == 0x3c) {
+      return tokenizeLessThan(next);
+    }
+    if (next == 0x3e) {
+      return tokenizeGreaterThan(next);
+    }
+    if (next == 0x3d) {
+      return tokenizeEquals(next);
+    }
+    if (next == 0x21) {
+      return tokenizeExclamation(next);
+    }
+    if (next == 0x2b) {
+      return tokenizePlus(next);
+    }
+    if (next == 0x2d) {
+      return tokenizeMinus(next);
+    }
+    if (next == 0x2a) {
+      return tokenizeMultiply(next);
+    }
+    if (next == 0x25) {
+      return tokenizePercent(next);
+    }
+    if (next == 0x26) {
+      return tokenizeAmpersand(next);
+    }
+    if (next == 0x7c) {
+      return tokenizeBar(next);
+    }
+    if (next == 0x5e) {
+      return tokenizeCaret(next);
+    }
+    if (next == 0x5b) {
+      return tokenizeOpenSquareBracket(next);
+    }
+    if (next == 0x7e) {
+      return tokenizeTilde(next);
+    }
+    if (next == 0x5c) {
+      appendToken(TokenType.BACKSLASH);
+      return advance();
+    }
+    if (next == 0x23) {
+      return tokenizeTag(next);
+    }
+    if (next == 0x28) {
+      appendBeginToken(TokenType.OPEN_PAREN);
+      return advance();
+    }
+    if (next == 0x29) {
+      appendEndToken(TokenType.CLOSE_PAREN, TokenType.OPEN_PAREN);
+      return advance();
+    }
+    if (next == 0x2c) {
+      appendToken(TokenType.COMMA);
+      return advance();
+    }
+    if (next == 0x3a) {
+      appendToken(TokenType.COLON);
+      return advance();
+    }
+    if (next == 0x3b) {
+      appendToken(TokenType.SEMICOLON);
+      return advance();
+    }
+    if (next == 0x3f) {
+      appendToken(TokenType.QUESTION);
+      return advance();
+    }
+    if (next == 0x5d) {
+      appendEndToken(TokenType.CLOSE_SQUARE_BRACKET, TokenType.OPEN_SQUARE_BRACKET);
+      return advance();
+    }
+    if (next == 0x60) {
+      appendToken(TokenType.BACKPING);
+      return advance();
+    }
+    if (next == 0x7b) {
+      appendBeginToken(TokenType.OPEN_CURLY_BRACKET);
+      return advance();
+    }
+    if (next == 0x7d) {
+      appendEndToken(TokenType.CLOSE_CURLY_BRACKET, TokenType.OPEN_CURLY_BRACKET);
+      return advance();
+    }
+    if (next == 0x2f) {
+      return tokenizeSlashOrComment(next);
+    }
+    if (next == 0x40) {
+      appendToken(TokenType.AT);
+      return advance();
+    }
+    if (next == 0x22 || next == 0x27) {
+      return tokenizeString(next, offset, false);
+    }
+    if (next == 0x2e) {
+      return tokenizeDotOrNumber(next);
+    }
+    if (next == 0x30) {
+      return tokenizeHexOrNumber(next);
+    }
+    if (0x31 <= next && next <= 0x39) {
+      return tokenizeNumber(next);
+    }
+    if (next == -1) {
+      return -1;
+    }
+    if (Character.isLetter(next)) {
+      return tokenizeIdentifier(next, offset, true);
+    }
+    if (next == AbstractScanner._$NBSP) {
+      return advance();
+    }
+    reportError(ScannerErrorCode.ILLEGAL_CHARACTER, [next]);
+    return advance();
+  }
+  /**
+   * Return the beginning token corresponding to a closing brace that was found while scanning
+   * inside a string interpolation expression. Tokens that cannot be matched with the closing brace
+   * will be dropped from the stack.
+   * @return the token to be paired with the closing brace
+   */
+  BeginToken findTokenMatchingClosingBraceInInterpolationExpression() {
+    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) {
+        return begin;
+      }
+      _hasUnmatchedGroups2 = true;
+      _groupingStack.removeAt(last);
+      last--;
+    }
+    return null;
+  }
+  Token firstToken() => _tokens.next;
+  /**
+   * Return the source being scanned.
+   * @return the source being scanned
+   */
+  Source get source => _source;
+  /**
+   * Report an error at the current offset.
+   * @param errorCode the error code indicating the nature of the error
+   * @param arguments any arguments needed to complete the error message
+   */
+  void reportError(ScannerErrorCode errorCode, List<Object> arguments) {
+    _errorListener.onError(new AnalysisError.con2(source, offset, 1, errorCode, [arguments]));
+  }
+  int select(int choice, TokenType yesType, TokenType noType) {
+    int next = advance();
+    if (next == choice) {
+      appendToken(yesType);
+      return advance();
+    } else {
+      appendToken(noType);
+      return next;
+    }
+  }
+  int select2(int choice, TokenType yesType, TokenType noType, int offset) {
+    int next = advance();
+    if (next == choice) {
+      appendToken2(yesType, offset);
+      return advance();
+    } else {
+      appendToken2(noType, offset);
+      return next;
+    }
+  }
+  int tokenizeAmpersand(int next) {
+    next = advance();
+    if (next == 0x26) {
+      appendToken(TokenType.AMPERSAND_AMPERSAND);
+      return advance();
+    } else if (next == 0x3d) {
+      appendToken(TokenType.AMPERSAND_EQ);
+      return advance();
+    } else {
+      appendToken(TokenType.AMPERSAND);
+      return next;
+    }
+  }
+  int tokenizeBar(int next) {
+    next = advance();
+    if (next == 0x7c) {
+      appendToken(TokenType.BAR_BAR);
+      return advance();
+    } else if (next == 0x3d) {
+      appendToken(TokenType.BAR_EQ);
+      return advance();
+    } else {
+      appendToken(TokenType.BAR);
+      return next;
+    }
+  }
+  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 {
+      appendToken(TokenType.PERIOD);
+      return next;
+    }
+  }
+  int tokenizeEquals(int next) {
+    next = advance();
+    if (next == 0x3d) {
+      appendToken(TokenType.EQ_EQ);
+      return advance();
+    } else if (next == 0x3e) {
+      appendToken(TokenType.FUNCTION);
+      return advance();
+    }
+    appendToken(TokenType.EQ);
+    return next;
+  }
+  int tokenizeExclamation(int next) {
+    next = advance();
+    if (next == 0x3d) {
+      appendToken(TokenType.BANG_EQ);
+      return advance();
+    }
+    appendToken(TokenType.BANG);
+    return next;
+  }
+  int tokenizeExponent(int next) {
+    if (next == 0x2b || next == 0x2d) {
+      next = advance();
+    }
+    bool hasDigits = false;
+    while (true) {
+      if (0x30 <= next && next <= 0x39) {
+        hasDigits = true;
+      } else {
+        if (!hasDigits) {
+          reportError(ScannerErrorCode.MISSING_DIGIT, []);
+        }
+        return next;
+      }
+      next = advance();
+    }
+  }
+  int tokenizeFractionPart(int next, int start) {
+    bool done = false;
+    bool hasDigit = false;
+    LOOP: while (!done) {
+      if (0x30 <= next && next <= 0x39) {
+        hasDigit = true;
+      } else if (0x65 == next || 0x45 == next) {
+        hasDigit = true;
+        next = tokenizeExponent(advance());
+        done = true;
+        continue LOOP;
+      } else {
+        done = true;
+        continue LOOP;
+      }
+      next = advance();
+    }
+    if (!hasDigit) {
+      appendStringToken(TokenType.INT, getString(start, -2));
+      if (0x2e == next) {
+        return select2(0x2e, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD, offset - 1);
+      }
+      appendToken2(TokenType.PERIOD, offset - 1);
+      return bigSwitch(next);
+    }
+    if (next == 0x64 || next == 0x44) {
+      next = advance();
+    }
+    appendStringToken(TokenType.DOUBLE, getString(start, next < 0 ? 0 : -1));
+    return next;
+  }
+  int tokenizeGreaterThan(int next) {
+    next = advance();
+    if (0x3d == next) {
+      appendToken(TokenType.GT_EQ);
+      return advance();
+    } else if (0x3e == next) {
+      next = advance();
+      if (0x3d == next) {
+        appendToken(TokenType.GT_GT_EQ);
+        return advance();
+      } else {
+        appendToken(TokenType.GT_GT);
+        return next;
+      }
+    } else {
+      appendToken(TokenType.GT);
+      return next;
+    }
+  }
+  int tokenizeHex(int next) {
+    int start = offset - 1;
+    bool hasDigits = false;
+    while (true) {
+      next = advance();
+      if ((0x30 <= next && next <= 0x39) || (0x41 <= next && next <= 0x46) || (0x61 <= next && next <= 0x66)) {
+        hasDigits = true;
+      } else {
+        if (!hasDigits) {
+          reportError(ScannerErrorCode.MISSING_HEX_DIGIT, []);
+        }
+        appendStringToken(TokenType.HEXADECIMAL, getString(start, next < 0 ? 0 : -1));
+        return next;
+      }
+    }
+  }
+  int tokenizeHexOrNumber(int next) {
+    int x = peek();
+    if (x == 0x78 || x == 0x58) {
+      advance();
+      return tokenizeHex(x);
+    }
+    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)) {
+      next = advance();
+    }
+    appendStringToken(TokenType.IDENTIFIER, getString(start, next < 0 ? 0 : -1));
+    return next;
+  }
+  int tokenizeInterpolatedExpression(int next, int start) {
+    appendBeginToken(TokenType.STRING_INTERPOLATION_EXPRESSION);
+    next = advance();
+    while (next != -1) {
+      if (next == 0x7d) {
+        BeginToken begin = findTokenMatchingClosingBraceInInterpolationExpression();
+        if (begin == null) {
+          beginToken();
+          appendToken(TokenType.CLOSE_CURLY_BRACKET);
+          next = advance();
+          beginToken();
+          return next;
+        } else if (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) {
+          beginToken();
+          appendEndToken(TokenType.CLOSE_CURLY_BRACKET, TokenType.STRING_INTERPOLATION_EXPRESSION);
+          next = advance();
+          beginToken();
+          return next;
+        }
+      } else {
+        next = bigSwitch(next);
+      }
+    }
+    if (next == -1) {
+      return next;
+    }
+    next = advance();
+    beginToken();
+    return next;
+  }
+  int tokenizeInterpolatedIdentifier(int next, int start) {
+    appendStringToken2(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 0);
+    beginToken();
+    next = tokenizeKeywordOrIdentifier(next, false);
+    beginToken();
+    return next;
+  }
+  int tokenizeKeywordOrIdentifier(int next, 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();
+    }
+    if (state == null || state.keyword() == null) {
+      return tokenizeIdentifier(next, start, allowDollar);
+    }
+    if ((0x41 <= next && next <= 0x5a) || (0x30 <= next && next <= 0x39) || next == 0x5f || next == 0x24) {
+      return tokenizeIdentifier(next, start, allowDollar);
+    } else if (next < 128) {
+      appendKeywordToken(state.keyword());
+      return next;
+    } else {
+      return tokenizeIdentifier(next, start, allowDollar);
+    }
+  }
+  int tokenizeLessThan(int next) {
+    next = advance();
+    if (0x3d == next) {
+      appendToken(TokenType.LT_EQ);
+      return advance();
+    } else if (0x3c == next) {
+      return select(0x3d, TokenType.LT_LT_EQ, TokenType.LT_LT);
+    } else {
+      appendToken(TokenType.LT);
+      return next;
+    }
+  }
+  int tokenizeMinus(int next) {
+    next = advance();
+    if (next == 0x2d) {
+      appendToken(TokenType.MINUS_MINUS);
+      return advance();
+    } else if (next == 0x3d) {
+      appendToken(TokenType.MINUS_EQ);
+      return advance();
+    } else {
+      appendToken(TokenType.MINUS);
+      return next;
+    }
+  }
+  int tokenizeMultiLineComment(int next) {
+    int nesting = 1;
+    next = advance();
+    while (true) {
+      if (-1 == next) {
+        reportError(ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT, []);
+        appendCommentToken(TokenType.MULTI_LINE_COMMENT, getString(_tokenStart, 0));
+        return next;
+      } else if (0x2a == next) {
+        next = advance();
+        if (0x2f == next) {
+          --nesting;
+          if (0 == nesting) {
+            appendCommentToken(TokenType.MULTI_LINE_COMMENT, getString(_tokenStart, 0));
+            return advance();
+          } else {
+            next = advance();
+          }
+        }
+      } else if (0x2f == next) {
+        next = advance();
+        if (0x2a == next) {
+          next = advance();
+          ++nesting;
+        }
+      } else {
+        next = advance();
+      }
+    }
+  }
+  int tokenizeMultiLineRawString(int quoteChar, int start) {
+    int next = advance();
+    outer: while (next != -1) {
+      while (next != quoteChar) {
+        next = advance();
+        if (next == -1) {
+          break outer;
+        }
+      }
+      next = advance();
+      if (next == quoteChar) {
+        next = advance();
+        if (next == quoteChar) {
+          appendStringToken(TokenType.STRING, getString(start, 0));
+          return advance();
+        }
+      }
+    }
+    reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
+    appendStringToken(TokenType.STRING, getString(start, 0));
+    return advance();
+  }
+  int tokenizeMultiLineString(int quoteChar, int start, bool raw) {
+    if (raw) {
+      return tokenizeMultiLineRawString(quoteChar, start);
+    }
+    int next = advance();
+    while (next != -1) {
+      if (next == 0x24) {
+        appendStringToken(TokenType.STRING, getString(start, -1));
+        beginToken();
+        next = tokenizeStringInterpolation(start);
+        start = offset;
+        continue;
+      }
+      if (next == quoteChar) {
+        next = advance();
+        if (next == quoteChar) {
+          next = advance();
+          if (next == quoteChar) {
+            appendStringToken(TokenType.STRING, getString(start, 0));
+            return advance();
+          }
+        }
+        continue;
+      }
+      if (next == 0x5c) {
+        next = advance();
+        if (next == -1) {
+          break;
+        }
+      }
+      next = advance();
+    }
+    reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
+    appendStringToken(TokenType.STRING, getString(start, 0));
+    return advance();
+  }
+  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) {
+        return tokenizeFractionPart(advance(), start);
+      } else if (next == 0x64 || next == 0x44) {
+        appendStringToken(TokenType.DOUBLE, getString(start, 0));
+        return advance();
+      } else if (next == 0x65 || next == 0x45) {
+        return tokenizeFractionPart(next, start);
+      } else {
+        appendStringToken(TokenType.INT, getString(start, next < 0 ? 0 : -1));
+        return next;
+      }
+    }
+  }
+  int tokenizeOpenSquareBracket(int next) {
+    next = advance();
+    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 tokenizePlus(int next) {
+    next = advance();
+    if (0x2b == next) {
+      appendToken(TokenType.PLUS_PLUS);
+      return advance();
+    } else if (0x3d == next) {
+      appendToken(TokenType.PLUS_EQ);
+      return advance();
+    } else {
+      appendToken(TokenType.PLUS);
+      return next;
+    }
+  }
+  int tokenizeSingleLineComment(int next) {
+    while (true) {
+      next = advance();
+      if (0xa == next || 0xd == next || -1 == next) {
+        appendCommentToken(TokenType.SINGLE_LINE_COMMENT, getString(_tokenStart, 0));
+        return next;
+      }
+    }
+  }
+  int tokenizeSingleLineRawString(int next, int quoteChar, int start) {
+    next = advance();
+    while (next != -1) {
+      if (next == quoteChar) {
+        appendStringToken(TokenType.STRING, getString(start, 0));
+        return advance();
+      } else if (next == 0xd || next == 0xa) {
+        reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
+        appendStringToken(TokenType.STRING, getString(start, 0));
+        return advance();
+      }
+      next = advance();
+    }
+    reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
+    appendStringToken(TokenType.STRING, getString(start, 0));
+    return advance();
+  }
+  int tokenizeSingleLineString(int next, int quoteChar, int start) {
+    while (next != quoteChar) {
+      if (next == 0x5c) {
+        next = advance();
+      } else if (next == 0x24) {
+        appendStringToken(TokenType.STRING, getString(start, -1));
+        beginToken();
+        next = tokenizeStringInterpolation(start);
+        start = offset;
+        continue;
+      }
+      if (next <= 0xd && (next == 0xa || next == 0xd || next == -1)) {
+        reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
+        appendStringToken(TokenType.STRING, getString(start, 0));
+        return advance();
+      }
+      next = advance();
+    }
+    appendStringToken(TokenType.STRING, getString(start, 0));
+    return advance();
+  }
+  int tokenizeSlashOrComment(int next) {
+    next = advance();
+    if (0x2a == next) {
+      return tokenizeMultiLineComment(next);
+    } else if (0x2f == next) {
+      return tokenizeSingleLineComment(next);
+    } else if (0x3d == next) {
+      appendToken(TokenType.SLASH_EQ);
+      return advance();
+    } else {
+      appendToken(TokenType.SLASH);
+      return next;
+    }
+  }
+  int tokenizeString(int next, int start, bool raw) {
+    int quoteChar = next;
+    next = advance();
+    if (quoteChar == next) {
+      next = advance();
+      if (quoteChar == next) {
+        return tokenizeMultiLineString(quoteChar, start, raw);
+      } else {
+        appendStringToken(TokenType.STRING, getString(start, -1));
+        return next;
+      }
+    }
+    if (raw) {
+      return tokenizeSingleLineRawString(next, quoteChar, start);
+    } else {
+      return tokenizeSingleLineString(next, quoteChar, start);
+    }
+  }
+  int tokenizeStringInterpolation(int start) {
+    beginToken();
+    int next = advance();
+    if (next == 0x7b) {
+      return tokenizeInterpolatedExpression(next, start);
+    } else {
+      return tokenizeInterpolatedIdentifier(next, start);
+    }
+  }
+  int tokenizeTag(int next) {
+    if (offset == 0) {
+      if (peek() == 0x21) {
+        do {
+          next = advance();
+        } while (next != 0xa && next != 0xd && next > 0);
+        appendStringToken(TokenType.SCRIPT_TAG, getString(_tokenStart, 0));
+        return next;
+      }
+    }
+    appendToken(TokenType.HASH);
+    return advance();
+  }
+  int tokenizeTilde(int next) {
+    next = advance();
+    if (next == 0x2f) {
+      return select(0x3d, TokenType.TILDE_SLASH_EQ, TokenType.TILDE_SLASH);
+    } else {
+      appendToken(TokenType.TILDE);
+      return next;
+    }
+  }
+}
+/**
+ * Instances of the class {@code KeywordTokenWithComment} implement a keyword token that is preceded
+ * by comments.
+ */
+class KeywordTokenWithComment extends KeywordToken {
+  /**
+   * The first comment in the list of comments that precede this token.
+   */
+  Token _precedingComment;
+  /**
+   * Initialize a newly created token to to represent the given keyword and to be preceded by the
+   * comments reachable from the given comment.
+   * @param keyword the keyword being represented by this token
+   * @param offset the offset from the beginning of the file to the first character in the token
+   * @param precedingComment the first comment in the list of comments that precede this token
+   */
+  KeywordTokenWithComment(Keyword keyword, int offset, Token precedingComment) : super(keyword, offset) {
+    this._precedingComment = precedingComment;
+  }
+  Token get precedingComments => _precedingComment;
+}
+/**
+ * Instances of the abstract class {@code KeywordState} represent a state in a state machine used to
+ * scan keywords.
+ */
+class KeywordState {
+  /**
+   * An empty transition table used by leaf states.
+   */
+  static List<KeywordState> _EMPTY_TABLE = new List<KeywordState>.fixedLength(26);
+  /**
+   * The initial state in the state machine.
+   */
+  static KeywordState KEYWORD_STATE = createKeywordStateTable();
+  /**
+   * Create the next state in the state machine where we have already recognized the subset of
+   * strings in the given array of strings starting at the given offset and having the given length.
+   * All of these strings have a common prefix and the next character is at the given start index.
+   * @param start the index of the character in the strings used to transition to a new state
+   * @param strings an array containing all of the strings that will be recognized by the state
+   * machine
+   * @param offset the offset of the first string in the array that has the prefix that is assumed
+   * to have been recognized by the time we reach the state being built
+   * @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) {
+    List<KeywordState> result = new List<KeywordState>.fixedLength(26);
+    assert(length != 0);
+    int chunk = 0x0;
+    int chunkStart = -1;
+    bool isLeaf = false;
+    for (int i = offset; i < offset + length; i++) {
+      if (strings[i].length == start) {
+        isLeaf = true;
+      }
+      if (strings[i].length > start) {
+        int c = strings[i].charCodeAt(start);
+        if (chunk != c) {
+          if (chunkStart != -1) {
+            result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkStart, i - chunkStart);
+          }
+          chunkStart = i;
+          chunk = c;
+        }
+      }
+    }
+    if (chunkStart != -1) {
+      assert(result[chunk - 0x61] == null);
+      result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkStart, offset + length - chunkStart);
+    } else {
+      assert(length == 1);
+      return new KeywordState(_EMPTY_TABLE, strings[offset]);
+    }
+    if (isLeaf) {
+      return new KeywordState(result, strings[offset]);
+    } else {
+      return new KeywordState(result, null);
+    }
+  }
+  /**
+   * Create the initial state in the state machine.
+   * @return the state that was created
+   */
+  static KeywordState createKeywordStateTable() {
+    List<Keyword> values2 = Keyword.values;
+    List<String> strings = new List<String>.fixedLength(values2.length);
+    for (int i = 0; i < values2.length; i++) {
+      strings[i] = values2[i].syntax;
+    }
+    strings.sort();
+    return computeKeywordStateTable(0, strings, 0, strings.length);
+  }
+  /**
+   * A table mapping characters to the states to which those characters will transition. (The index
+   * into the array is the offset from the character {@code 'a'} to the transitioning character.)
+   */
+  List<KeywordState> _table;
+  /**
+   * The keyword that is recognized by this state, or {@code null} if this state is not a terminal
+   * state.
+   */
+  Keyword _keyword2;
+  /**
+   * Initialize a newly created state to have the given transitions and to recognize the keyword
+   * with the given syntax.
+   * @param table a table mapping characters to the states to which those characters will transition
+   * @param syntax the syntax of the keyword that is recognized by the state
+   */
+  KeywordState(List<KeywordState> table, String syntax) {
+    this._table = table;
+    this._keyword2 = (syntax == null) ? null : Keyword.keywords[syntax];
+  }
+  /**
+   * Return the keyword that was recognized by this state, or {@code null} if this state does not
+   * recognized a keyword.
+   * @return the keyword that was matched by reaching this state
+   */
+  Keyword keyword() => _keyword2;
+  /**
+   * Return the state that follows this state on a transition of the given character, or{@code null} if there is no valid state reachable from this state with such a transition.
+   * @param c the character used to transition from this state to another state
+   * @return the state that follows this state on a transition of the given character
+   */
+  KeywordState next(int c) => _table[c - 0x61];
+}
\ 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
new file mode 100644
index 0000000..4efbb17
--- /dev/null
+++ b/pkg/analyzer-experimental/lib/src/generated/source.dart
@@ -0,0 +1,148 @@
+// 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.source;
+
+import 'java_core.dart';
+
+/**
+ * The interface {@code Source} defines the behavior of objects representing source code that can be
+ * compiled.
+ */
+abstract class Source {
+  /**
+   * Return {@code true} if the given object is a source that represents the same source code as
+   * this source.
+   * @param object the object to be compared with this object
+   * @return {@code true} if the given object is a source that represents the same source code as
+   * this source
+   * @see Object#equals(Object)
+   */
+  bool operator ==(Object object);
+  /**
+   * Get the contents of this source and pass it to the given receiver. Exactly one of the methods
+   * defined on the receiver will be invoked unless an exception is thrown. The method that will be
+   * invoked depends on which of the possible representations of the contents is the most efficient.
+   * Whichever method is invoked, it will be invoked before this method returns.
+   * @param receiver the content receiver to which the content of this source will be passed
+   * @throws Exception if the contents of this source could not be accessed
+   */
+  void getContents(Source_ContentReceiver receiver);
+  /**
+   * Return the full (long) version of the name that can be displayed to the user to denote this
+   * source. For example, for a source representing a file this would typically be the absolute path
+   * of the file.
+   * @return a name that can be displayed to the user to denote this source
+   */
+  String get fullName;
+  /**
+   * Return a short version of the name that can be displayed to the user to denote this source. For
+   * example, for a source representing a file this would typically be the name of the file.
+   * @return a name that can be displayed to the user to denote this source
+   */
+  String get shortName;
+  /**
+   * Return a hash code for this source.
+   * @return a hash code for this source
+   * @see Object#hashCode()
+   */
+  int get hashCode;
+  /**
+   * Return {@code true} if this source is in one of the system libraries.
+   * @return {@code true} if this is in a system library
+   */
+  bool isInSystemLibrary();
+  /**
+   * Resolve the given URI relative to the location of this source.
+   * @param uri the URI to be resolved against this source
+   * @return a source representing the resolved URI
+   */
+  Source resolve(String uri);
+}
+/**
+ * The interface {@code ContentReceiver} defines the behavior of objects that can receive the
+ * content of a source.
+ */
+abstract class Source_ContentReceiver {
+  /**
+   * Accept the contents of a source represented as a character buffer.
+   * @param contents the contents of the source
+   */
+  accept(CharBuffer contents);
+  /**
+   * Accept the contents of a source represented as a string.
+   * @param contents the contents of the source
+   */
+  void accept2(String contents);
+}
+/**
+ * Instances of the class {@code LineInfo} encapsulate information about line and column information
+ * within a source file.
+ */
+class LineInfo {
+  /**
+   * An array containing the offsets of the first character of each line in the source code.
+   */
+  List<int> _lineStarts;
+  /**
+   * Initialize a newly created set of line information to represent the data encoded in the given
+   * array.
+   * @param lineStarts the offsets of the first character of each line in the source code
+   */
+  LineInfo(List<int> lineStarts) {
+    if (lineStarts == null) {
+      throw new IllegalArgumentException("lineStarts must be non-null");
+    } else if (lineStarts.length < 1) {
+      throw new IllegalArgumentException("lineStarts must be non-empty");
+    }
+    this._lineStarts = lineStarts;
+  }
+  /**
+   * Return the location information for the character at the given offset.
+   * @param offset the offset of the character for which location information is to be returned
+   * @return the location information for the character at the given offset
+   */
+  LineInfo_Location getLocation(int offset) {
+    int lineCount = _lineStarts.length;
+    for (int i = 1; i < lineCount; i++) {
+      if (offset < _lineStarts[i]) {
+        return new LineInfo_Location(i, offset - _lineStarts[i - 1] + 1);
+      }
+    }
+    return new LineInfo_Location(lineCount, offset - _lineStarts[lineCount - 1] + 1);
+  }
+}
+/**
+ * Instances of the class {@code Location} represent the location of a character as a line and
+ * column pair.
+ */
+class LineInfo_Location {
+  /**
+   * The one-based index of the line containing the character.
+   */
+  int _lineNumber = 0;
+  /**
+   * The one-based index of the column containing the character.
+   */
+  int _columnNumber = 0;
+  /**
+   * Initialize a newly created location to represent the location of the character at the given
+   * line and column position.
+   * @param lineNumber the one-based index of the line containing the character
+   * @param columnNumber the one-based index of the column containing the character
+   */
+  LineInfo_Location(int lineNumber, int columnNumber) {
+    this._lineNumber = lineNumber;
+    this._columnNumber = columnNumber;
+  }
+  /**
+   * Return the one-based index of the column containing the character.
+   * @return the one-based index of the column containing the character
+   */
+  int get columnNumber => _columnNumber;
+  /**
+   * Return the one-based index of the line containing the character.
+   * @return the one-based index of the line containing the character
+   */
+  int get lineNumber => _lineNumber;
+}
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/lib/src/generated/utilities_dart.dart b/pkg/analyzer-experimental/lib/src/generated/utilities_dart.dart
new file mode 100644
index 0000000..de12488
--- /dev/null
+++ b/pkg/analyzer-experimental/lib/src/generated/utilities_dart.dart
@@ -0,0 +1,36 @@
+// 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.utilities.dart;
+
+
+/**
+ * The enumeration {@code ParameterKind} defines the different kinds of parameters. There are two
+ * basic kinds of parameters: required and optional. Optional parameters are further divided into
+ * two kinds: positional optional and named optional.
+ */
+class ParameterKind {
+  static final ParameterKind REQUIRED = new ParameterKind('REQUIRED', 0, false);
+  static final ParameterKind POSITIONAL = new ParameterKind('POSITIONAL', 1, true);
+  static final ParameterKind NAMED = new ParameterKind('NAMED', 2, true);
+  static final List<ParameterKind> values = [REQUIRED, POSITIONAL, NAMED];
+  final String __name;
+  final int __ordinal;
+  /**
+   * A flag indicating whether this is an optional parameter.
+   */
+  bool _isOptional2 = false;
+  /**
+   * Initialize a newly created kind with the given state.
+   * @param isOptional {@code true} if this is an optional parameter
+   */
+  ParameterKind(this.__name, this.__ordinal, bool isOptional) {
+    this._isOptional2 = isOptional;
+  }
+  /**
+   * Return {@code true} if this is an optional parameter.
+   * @return {@code true} if this is an optional parameter
+   */
+  bool isOptional() => _isOptional2;
+  String toString() => __name;
+}
\ 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
new file mode 100644
index 0000000..efeded0
--- /dev/null
+++ b/pkg/analyzer-experimental/test/generated/parser_test.dart
@@ -0,0 +1,8218 @@
+// 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.parser_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/parser.dart';
+import 'package:analyzer-experimental/src/generated/utilities_dart.dart';
+import 'package:unittest/unittest.dart' as _ut;
+import 'test_support.dart';
+import 'scanner_test.dart' show TokenFactory;
+
+class ParserTestCase extends EngineTestCase {
+  /**
+   * An empty array of objects used as arguments to zero-argument methods.
+   */
+  static List<Object> _EMPTY_ARGUMENTS = new List<Object>.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.
+   * <p>
+   * The given source is scanned and the parser is initialized to start with the first token in the
+   * source before the parse method is invoked.
+   * @param methodName the name of the parse method that should be invoked to parse the source
+   * @param objects the values of the arguments to the method
+   * @param source the source to be parsed by the parse method
+   * @return the result of invoking the method
+   * @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));
+  /**
+   * 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.
+   * <p>
+   * The given source is scanned and the parser is initialized to start with the first token in the
+   * source before the parse method is invoked.
+   * @param methodName the name of the parse method that should be invoked to parse the source
+   * @param objects the values of the arguments to the method
+   * @param source the source to be parsed by the parse method
+   * @param errorCodes the error codes of the errors that should be generated
+   * @return the result of invoking the method
+   * @throws Exception if the method could not be invoked or throws an exception
+   * @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) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    Object result = invokeParserMethod(methodName, objects, source, listener);
+    listener.assertErrors(errors);
+    return result;
+  }
+  /**
+   * 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.
+   * <p>
+   * The given source is scanned and the parser is initialized to start with the first token in the
+   * source before the parse method is invoked.
+   * @param methodName the name of the parse method that should be invoked to parse the source
+   * @param objects the values of the arguments to the method
+   * @param source the source to be parsed by the parse method
+   * @param errorCodes the error codes of the errors that should be generated
+   * @return the result of invoking the method
+   * @throws Exception if the method could not be invoked or throws an exception
+   * @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) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    Object result = invokeParserMethod(methodName, objects, source, listener);
+    listener.assertErrors2(errorCodes);
+    return result;
+  }
+  /**
+   * Invoke a parse method in {@link Parser}. The method is assumed to have no arguments.
+   * <p>
+   * The given source is scanned and the parser is initialized to start with the first token in the
+   * source before the parse method is invoked.
+   * @param methodName the name of the parse method that should be invoked to parse the source
+   * @param source the source to be parsed by the parse method
+   * @param errorCodes the error codes of the errors that should be generated
+   * @return the result of invoking the method
+   * @throws Exception if the method could not be invoked or throws an exception
+   * @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);
+  /**
+   * Parse the given source as a compilation unit.
+   * @param source the source to be parsed
+   * @param errorCodes the error codes of the errors that are expected to be found
+   * @return the compilation unit that was parsed
+   * @throws Exception if the source could not be parsed, if the compilation errors in the source do
+   * not match those that are expected, or if the result would have been {@code null}
+   */
+  static CompilationUnit parseCompilationUnit(String source, List<ErrorCode> errorCodes) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    StringScanner scanner = new StringScanner(null, source, listener);
+    listener.setLineInfo(new TestSource(), scanner.lineStarts);
+    Token token = scanner.tokenize();
+    Parser parser = new Parser(null, listener);
+    CompilationUnit unit = parser.parseCompilationUnit(token);
+    JUnitTestCase.assertNotNull(unit);
+    listener.assertErrors2(errorCodes);
+    return unit;
+  }
+  /**
+   * Parse the given source as an expression.
+   * @param source the source to be parsed
+   * @param errorCodes the error codes of the errors that are expected to be found
+   * @return the expression that was parsed
+   * @throws Exception if the source could not be parsed, if the compilation errors in the source do
+   * not match those that are expected, or if the result would have been {@code null}
+   */
+  static Expression parseExpression(String source, List<ErrorCode> errorCodes) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    StringScanner scanner = new StringScanner(null, source, listener);
+    listener.setLineInfo(new TestSource(), scanner.lineStarts);
+    Token token = scanner.tokenize();
+    Parser parser = new Parser(null, listener);
+    Expression expression = parser.parseExpression(token);
+    JUnitTestCase.assertNotNull(expression);
+    listener.assertErrors2(errorCodes);
+    return expression as Expression;
+  }
+  /**
+   * Parse the given source as a statement.
+   * @param source the source to be parsed
+   * @param errorCodes the error codes of the errors that are expected to be found
+   * @return the statement that was parsed
+   * @throws Exception if the source could not be parsed, if the compilation errors in the source do
+   * not match those that are expected, or if the result would have been {@code null}
+   */
+  static Statement parseStatement(String source, List<ErrorCode> errorCodes) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    StringScanner scanner = new StringScanner(null, source, listener);
+    listener.setLineInfo(new TestSource(), scanner.lineStarts);
+    Token token = scanner.tokenize();
+    Parser parser = new Parser(null, listener);
+    Statement statement = parser.parseStatement(token);
+    JUnitTestCase.assertNotNull(statement);
+    listener.assertErrors2(errorCodes);
+    return statement as Statement;
+  }
+  /**
+   * Parse the given source as a sequence of statements.
+   * @param source the source to be parsed
+   * @param expectedCount the number of statements that are expected
+   * @param errorCodes the error codes of the errors that are expected to be found
+   * @return the statements that were parsed
+   * @throws Exception if the source could not be parsed, if the number of statements does not match
+   * the expected count, if the compilation errors in the source do not match those that
+   * are expected, or if the result would have been {@code null}
+   */
+  static List<Statement> parseStatements(String source, int expectedCount, List<ErrorCode> errorCodes) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    StringScanner scanner = new StringScanner(null, source, listener);
+    listener.setLineInfo(new TestSource(), scanner.lineStarts);
+    Token token = scanner.tokenize();
+    Parser parser = new Parser(null, listener);
+    List<Statement> statements = parser.parseStatements(token);
+    EngineTestCase.assertSize(expectedCount, statements);
+    listener.assertErrors2(errorCodes);
+    return statements;
+  }
+  /**
+   * Invoke a 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.
+   * <p>
+   * The given source is scanned and the parser is initialized to start with the first token in the
+   * source before the method is invoked.
+   * @param methodName the name of the method that should be invoked
+   * @param objects the values of the arguments to the method
+   * @param source the source to be processed by the parse method
+   * @param listener the error listener that will be used for both scanning and parsing
+   * @return the result of invoking the method
+   * @throws Exception if the method could not be invoked or throws an exception
+   * @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 invokeParserMethod(String methodName, List<Object> objects, String source, GatheringErrorListener listener) {
+    StringScanner scanner = new StringScanner(null, source, listener);
+    Token tokenStream = scanner.tokenize();
+    listener.setLineInfo(new TestSource(), scanner.lineStarts);
+    Parser parser = new Parser(null, listener);
+    Object result = invokeParserMethodImpl(parser, methodName, objects, tokenStream);
+    JUnitTestCase.assertNotNull(result);
+    return result as Object;
+  }
+  /**
+   * Invoke a method in {@link Parser}. The method is assumed to have no arguments.
+   * <p>
+   * The given source is scanned and the parser is initialized to start with the first token in the
+   * source before the method is invoked.
+   * @param methodName the name of the method that should be invoked
+   * @param source the source to be processed by the parse method
+   * @param listener the error listener that will be used for both scanning and parsing
+   * @return the result of invoking the method
+   * @throws Exception if the method could not be invoked or throws an exception
+   * @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);
+  /**
+   * Return a CommentAndMetadata object with the given values that can be used for testing.
+   * @param comment the comment to be wrapped in the object
+   * @param annotations the annotations to be wrapped in the object
+   * @return a CommentAndMetadata object that can be used for testing
+   */
+  CommentAndMetadata commentAndMetadata(Comment comment, List<Annotation> annotations) {
+    List<Annotation> metadata = new List<Annotation>();
+    for (Annotation annotation in annotations) {
+      metadata.add(annotation);
+    }
+    return new CommentAndMetadata(comment, metadata);
+  }
+  /**
+   * Return an empty CommentAndMetadata object that can be used for testing.
+   * @return an empty CommentAndMetadata object that can be used for testing
+   */
+  CommentAndMetadata emptyCommentAndMetadata() => new CommentAndMetadata(null, new List<Annotation>());
+  static dartSuite() {
+    _ut.group('ParserTestCase', () {
+    });
+  }
+}
+/**
+ * Instances of the class {@code ASTValidator} are used to validate the correct construction of an
+ * AST structure.
+ */
+class ASTValidator extends GeneralizingASTVisitor<Object> {
+  /**
+   * A list containing the errors found while traversing the AST structure.
+   */
+  List<String> _errors = new List<String>();
+  /**
+   * Assert that no errors were found while traversing any of the AST structures that have been
+   * visited.
+   */
+  void assertValid() {
+    if (!_errors.isEmpty) {
+      StringBuffer builder = new StringBuffer();
+      builder.add("Invalid AST structure:");
+      for (String message in _errors) {
+        builder.add("\r\n   ");
+        builder.add(message);
+      }
+      JUnitTestCase.fail(builder.toString());
+    }
+  }
+  Object visitNode(ASTNode node) {
+    validate(node);
+    return super.visitNode(node);
+  }
+  /**
+   * Validate that the given AST node is correctly constructed.
+   * @param node the AST node being validated
+   */
+  void validate(ASTNode node) {
+    ASTNode parent12 = node.parent;
+    if (node is CompilationUnit) {
+      if (parent12 != null) {
+        _errors.add("Compilation units should not have a parent");
+      }
+    } else {
+      if (parent12 == null) {
+        _errors.add("No parent for ${node.runtimeType.toString()}");
+      }
+    }
+    if (node.beginToken == null) {
+      _errors.add("No begin token for ${node.runtimeType.toString()}");
+    }
+    if (node.endToken == null) {
+      _errors.add("No end token for ${node.runtimeType.toString()}");
+    }
+    int nodeStart = node.offset;
+    int nodeLength = node.length;
+    if (nodeStart < 0 || nodeLength < 0) {
+      _errors.add("No source info for ${node.runtimeType.toString()}");
+    }
+    if (parent12 != null) {
+      int nodeEnd = nodeStart + nodeLength;
+      int parentStart = parent12.offset;
+      int parentEnd = parentStart + parent12.length;
+      if (nodeStart < parentStart) {
+        _errors.add("Invalid source start (${nodeStart}) for ${node.runtimeType.toString()} inside ${parent12.runtimeType.toString()} (${parentStart})");
+      }
+      if (nodeEnd > parentEnd) {
+        _errors.add("Invalid source end (${nodeEnd}) for ${node.runtimeType.toString()} inside ${parent12.runtimeType.toString()} (${parentStart})");
+      }
+    }
+  }
+}
+/**
+ * The class {@code RecoveryParserTest} defines parser tests that test the parsing of invalid code
+ * sequences to ensure that the correct recovery steps are taken in the parser.
+ */
+class RecoveryParserTest extends ParserTestCase {
+  void test_additiveExpression_missing_LHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("+ y", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+  }
+  void test_additiveExpression_missing_LHS_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("+", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_additiveExpression_missing_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x +", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_additiveExpression_missing_RHS_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super +", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_additiveExpression_precedence_multiplicative_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("* +", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_additiveExpression_precedence_multiplicative_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("+ *", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_additiveExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super + +", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_argumentDefinitionTest_missing_identifier() {
+    ArgumentDefinitionTest expression = ParserTestCase.parseExpression("?", [ParserErrorCode.MISSING_IDENTIFIER]);
+    JUnitTestCase.assertTrue(expression.identifier.isSynthetic());
+  }
+  void test_assignmentExpression_missing_compound1() {
+    AssignmentExpression expression = ParserTestCase.parseExpression("= y = 0", []);
+    Expression syntheticExpression = expression.leftHandSide;
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
+    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
+  }
+  void test_assignmentExpression_missing_compound2() {
+    AssignmentExpression expression = ParserTestCase.parseExpression("x = = 0", []);
+    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;
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
+    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
+  }
+  void test_assignmentExpression_missing_LHS() {
+    AssignmentExpression expression = ParserTestCase.parseExpression("= 0", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftHandSide);
+    JUnitTestCase.assertTrue(expression.leftHandSide.isSynthetic());
+  }
+  void test_assignmentExpression_missing_RHS() {
+    AssignmentExpression expression = ParserTestCase.parseExpression("x =", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftHandSide);
+    JUnitTestCase.assertTrue(expression.rightHandSide.isSynthetic());
+  }
+  void test_bitwiseAndExpression_missing_LHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("& y", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+  }
+  void test_bitwiseAndExpression_missing_LHS_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("&", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_bitwiseAndExpression_missing_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x &", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_bitwiseAndExpression_missing_RHS_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super &", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_bitwiseAndExpression_precedence_equality_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("== &", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_bitwiseAndExpression_precedence_equality_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("& ==", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_bitwiseAndExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super &  &", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_bitwiseOrExpression_missing_LHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("| y", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+  }
+  void test_bitwiseOrExpression_missing_LHS_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("|", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_bitwiseOrExpression_missing_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x |", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_bitwiseOrExpression_missing_RHS_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super |", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_bitwiseOrExpression_precedence_xor_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("^ |", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_bitwiseOrExpression_precedence_xor_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("| ^", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_bitwiseOrExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super |  |", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_bitwiseXorExpression_missing_LHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("^ y", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+  }
+  void test_bitwiseXorExpression_missing_LHS_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("^", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_bitwiseXorExpression_missing_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x ^", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_bitwiseXorExpression_missing_RHS_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super ^", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_bitwiseXorExpression_precedence_and_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("& ^", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_bitwiseXorExpression_precedence_and_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("^ &", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_bitwiseXorExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super ^  ^", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_conditionalExpression_missingElse() {
+    ConditionalExpression expression = ParserTestCase.parse4("parseConditionalExpression", "x ? y :", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.elseExpression);
+    JUnitTestCase.assertTrue(expression.elseExpression.isSynthetic());
+  }
+  void test_conditionalExpression_missingThen() {
+    ConditionalExpression expression = ParserTestCase.parse4("parseConditionalExpression", "x ? : z", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.thenExpression);
+    JUnitTestCase.assertTrue(expression.thenExpression.isSynthetic());
+  }
+  void test_equalityExpression_missing_LHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("== y", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+  }
+  void test_equalityExpression_missing_LHS_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("==", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_equalityExpression_missing_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x ==", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_equalityExpression_missing_RHS_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super ==", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_equalityExpression_precedence_relational_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("is ==", [ParserErrorCode.MISSING_IDENTIFIER]);
+    EngineTestCase.assertInstanceOf(IsExpression, expression.leftOperand);
+  }
+  void test_equalityExpression_precedence_relational_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("== is", [ParserErrorCode.MISSING_IDENTIFIER]);
+    EngineTestCase.assertInstanceOf(IsExpression, expression.rightOperand);
+  }
+  void test_equalityExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super ==  ==", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_expressionList_multiple_end() {
+    List<Expression> result = ParserTestCase.parse4("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", []);
+    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,", []);
+    EngineTestCase.assertSize(4, result);
+    Expression syntheticExpression = result[3];
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, syntheticExpression);
+    JUnitTestCase.assertTrue(syntheticExpression.isSynthetic());
+  }
+  void test_logicalAndExpression_missing_LHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("&& y", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+  }
+  void test_logicalAndExpression_missing_LHS_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("&&", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_logicalAndExpression_missing_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x &&", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_logicalAndExpression_precedence_bitwiseOr_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("| &&", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_logicalAndExpression_precedence_bitwiseOr_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("&& |", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_logicalOrExpression_missing_LHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("|| y", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+  }
+  void test_logicalOrExpression_missing_LHS_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("||", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_logicalOrExpression_missing_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x ||", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_logicalOrExpression_precedence_logicalAnd_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("&& ||", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_logicalOrExpression_precedence_logicalAnd_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("|| &&", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_multiplicativeExpression_missing_LHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("* y", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+  }
+  void test_multiplicativeExpression_missing_LHS_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("*", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_multiplicativeExpression_missing_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x *", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_multiplicativeExpression_missing_RHS_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super *", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_multiplicativeExpression_precedence_unary_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("-x *", []);
+    EngineTestCase.assertInstanceOf(PrefixExpression, expression.leftOperand);
+  }
+  void test_multiplicativeExpression_precedence_unary_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("* -y", []);
+    EngineTestCase.assertInstanceOf(PrefixExpression, expression.rightOperand);
+  }
+  void test_multiplicativeExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super ==  ==", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_prefixExpression_missing_operand_minus() {
+    PrefixExpression expression = ParserTestCase.parseExpression("-", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.operand);
+    JUnitTestCase.assertTrue(expression.operand.isSynthetic());
+    JUnitTestCase.assertEquals(TokenType.MINUS, expression.operator.type);
+  }
+  void test_relationalExpression_missing_LHS() {
+    IsExpression expression = ParserTestCase.parseExpression("is y", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.expression);
+    JUnitTestCase.assertTrue(expression.expression.isSynthetic());
+  }
+  void test_relationalExpression_missing_LHS_RHS() {
+    IsExpression expression = ParserTestCase.parseExpression("is", [ParserErrorCode.MISSING_IDENTIFIER]);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.expression);
+    JUnitTestCase.assertTrue(expression.expression.isSynthetic());
+    EngineTestCase.assertInstanceOf(TypeName, expression.type);
+    JUnitTestCase.assertTrue(expression.type.isSynthetic());
+  }
+  void test_relationalExpression_missing_RHS() {
+    IsExpression expression = ParserTestCase.parseExpression("x is", [ParserErrorCode.MISSING_IDENTIFIER]);
+    EngineTestCase.assertInstanceOf(TypeName, expression.type);
+    JUnitTestCase.assertTrue(expression.type.isSynthetic());
+  }
+  void test_relationalExpression_precedence_shift_right() {
+    IsExpression expression = ParserTestCase.parseExpression("<< is", [ParserErrorCode.MISSING_IDENTIFIER]);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.expression);
+  }
+  void test_shiftExpression_missing_LHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("<< y", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+  }
+  void test_shiftExpression_missing_LHS_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("<<", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    JUnitTestCase.assertTrue(expression.leftOperand.isSynthetic());
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_shiftExpression_missing_RHS() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x <<", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_shiftExpression_missing_RHS_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super <<", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.rightOperand);
+    JUnitTestCase.assertTrue(expression.rightOperand.isSynthetic());
+  }
+  void test_shiftExpression_precedence_unary_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("+ <<", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_shiftExpression_precedence_unary_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("<< +", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_shiftExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super << <<", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_topLevelExternalFunction_extraSemicolon() {
+    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;
+    JUnitTestCase.assertNotNull(declaration);
+  }
+  static dartSuite() {
+    _ut.group('RecoveryParserTest', () {
+      _ut.test('test_additiveExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_additiveExpression_missing_LHS);
+      });
+      _ut.test('test_additiveExpression_missing_LHS_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_additiveExpression_missing_LHS_RHS);
+      });
+      _ut.test('test_additiveExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_additiveExpression_missing_RHS);
+      });
+      _ut.test('test_additiveExpression_missing_RHS_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_additiveExpression_missing_RHS_super);
+      });
+      _ut.test('test_additiveExpression_precedence_multiplicative_left', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_additiveExpression_precedence_multiplicative_left);
+      });
+      _ut.test('test_additiveExpression_precedence_multiplicative_right', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_additiveExpression_precedence_multiplicative_right);
+      });
+      _ut.test('test_additiveExpression_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_additiveExpression_super);
+      });
+      _ut.test('test_argumentDefinitionTest_missing_identifier', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_argumentDefinitionTest_missing_identifier);
+      });
+      _ut.test('test_assignmentExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_assignmentExpression_missing_LHS);
+      });
+      _ut.test('test_assignmentExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_assignmentExpression_missing_RHS);
+      });
+      _ut.test('test_assignmentExpression_missing_compound1', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_assignmentExpression_missing_compound1);
+      });
+      _ut.test('test_assignmentExpression_missing_compound2', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_assignmentExpression_missing_compound2);
+      });
+      _ut.test('test_assignmentExpression_missing_compound3', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_assignmentExpression_missing_compound3);
+      });
+      _ut.test('test_bitwiseAndExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseAndExpression_missing_LHS);
+      });
+      _ut.test('test_bitwiseAndExpression_missing_LHS_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseAndExpression_missing_LHS_RHS);
+      });
+      _ut.test('test_bitwiseAndExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseAndExpression_missing_RHS);
+      });
+      _ut.test('test_bitwiseAndExpression_missing_RHS_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseAndExpression_missing_RHS_super);
+      });
+      _ut.test('test_bitwiseAndExpression_precedence_equality_left', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseAndExpression_precedence_equality_left);
+      });
+      _ut.test('test_bitwiseAndExpression_precedence_equality_right', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseAndExpression_precedence_equality_right);
+      });
+      _ut.test('test_bitwiseAndExpression_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseAndExpression_super);
+      });
+      _ut.test('test_bitwiseOrExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseOrExpression_missing_LHS);
+      });
+      _ut.test('test_bitwiseOrExpression_missing_LHS_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseOrExpression_missing_LHS_RHS);
+      });
+      _ut.test('test_bitwiseOrExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseOrExpression_missing_RHS);
+      });
+      _ut.test('test_bitwiseOrExpression_missing_RHS_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseOrExpression_missing_RHS_super);
+      });
+      _ut.test('test_bitwiseOrExpression_precedence_xor_left', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseOrExpression_precedence_xor_left);
+      });
+      _ut.test('test_bitwiseOrExpression_precedence_xor_right', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseOrExpression_precedence_xor_right);
+      });
+      _ut.test('test_bitwiseOrExpression_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseOrExpression_super);
+      });
+      _ut.test('test_bitwiseXorExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseXorExpression_missing_LHS);
+      });
+      _ut.test('test_bitwiseXorExpression_missing_LHS_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseXorExpression_missing_LHS_RHS);
+      });
+      _ut.test('test_bitwiseXorExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseXorExpression_missing_RHS);
+      });
+      _ut.test('test_bitwiseXorExpression_missing_RHS_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseXorExpression_missing_RHS_super);
+      });
+      _ut.test('test_bitwiseXorExpression_precedence_and_left', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseXorExpression_precedence_and_left);
+      });
+      _ut.test('test_bitwiseXorExpression_precedence_and_right', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseXorExpression_precedence_and_right);
+      });
+      _ut.test('test_bitwiseXorExpression_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_bitwiseXorExpression_super);
+      });
+      _ut.test('test_conditionalExpression_missingElse', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_conditionalExpression_missingElse);
+      });
+      _ut.test('test_conditionalExpression_missingThen', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_conditionalExpression_missingThen);
+      });
+      _ut.test('test_equalityExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_equalityExpression_missing_LHS);
+      });
+      _ut.test('test_equalityExpression_missing_LHS_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_equalityExpression_missing_LHS_RHS);
+      });
+      _ut.test('test_equalityExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_equalityExpression_missing_RHS);
+      });
+      _ut.test('test_equalityExpression_missing_RHS_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_equalityExpression_missing_RHS_super);
+      });
+      _ut.test('test_equalityExpression_precedence_relational_left', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_equalityExpression_precedence_relational_left);
+      });
+      _ut.test('test_equalityExpression_precedence_relational_right', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_equalityExpression_precedence_relational_right);
+      });
+      _ut.test('test_equalityExpression_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_equalityExpression_super);
+      });
+      _ut.test('test_expressionList_multiple_end', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_expressionList_multiple_end);
+      });
+      _ut.test('test_expressionList_multiple_middle', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_expressionList_multiple_middle);
+      });
+      _ut.test('test_expressionList_multiple_start', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_expressionList_multiple_start);
+      });
+      _ut.test('test_logicalAndExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_logicalAndExpression_missing_LHS);
+      });
+      _ut.test('test_logicalAndExpression_missing_LHS_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_logicalAndExpression_missing_LHS_RHS);
+      });
+      _ut.test('test_logicalAndExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_logicalAndExpression_missing_RHS);
+      });
+      _ut.test('test_logicalAndExpression_precedence_bitwiseOr_left', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_logicalAndExpression_precedence_bitwiseOr_left);
+      });
+      _ut.test('test_logicalAndExpression_precedence_bitwiseOr_right', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_logicalAndExpression_precedence_bitwiseOr_right);
+      });
+      _ut.test('test_logicalOrExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_logicalOrExpression_missing_LHS);
+      });
+      _ut.test('test_logicalOrExpression_missing_LHS_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_logicalOrExpression_missing_LHS_RHS);
+      });
+      _ut.test('test_logicalOrExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_logicalOrExpression_missing_RHS);
+      });
+      _ut.test('test_logicalOrExpression_precedence_logicalAnd_left', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_logicalOrExpression_precedence_logicalAnd_left);
+      });
+      _ut.test('test_logicalOrExpression_precedence_logicalAnd_right', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_logicalOrExpression_precedence_logicalAnd_right);
+      });
+      _ut.test('test_multiplicativeExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_multiplicativeExpression_missing_LHS);
+      });
+      _ut.test('test_multiplicativeExpression_missing_LHS_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_multiplicativeExpression_missing_LHS_RHS);
+      });
+      _ut.test('test_multiplicativeExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_multiplicativeExpression_missing_RHS);
+      });
+      _ut.test('test_multiplicativeExpression_missing_RHS_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_multiplicativeExpression_missing_RHS_super);
+      });
+      _ut.test('test_multiplicativeExpression_precedence_unary_left', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_multiplicativeExpression_precedence_unary_left);
+      });
+      _ut.test('test_multiplicativeExpression_precedence_unary_right', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_multiplicativeExpression_precedence_unary_right);
+      });
+      _ut.test('test_multiplicativeExpression_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_multiplicativeExpression_super);
+      });
+      _ut.test('test_prefixExpression_missing_operand_minus', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_prefixExpression_missing_operand_minus);
+      });
+      _ut.test('test_relationalExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_relationalExpression_missing_LHS);
+      });
+      _ut.test('test_relationalExpression_missing_LHS_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_relationalExpression_missing_LHS_RHS);
+      });
+      _ut.test('test_relationalExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_relationalExpression_missing_RHS);
+      });
+      _ut.test('test_relationalExpression_precedence_shift_right', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_relationalExpression_precedence_shift_right);
+      });
+      _ut.test('test_shiftExpression_missing_LHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_shiftExpression_missing_LHS);
+      });
+      _ut.test('test_shiftExpression_missing_LHS_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_shiftExpression_missing_LHS_RHS);
+      });
+      _ut.test('test_shiftExpression_missing_RHS', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_shiftExpression_missing_RHS);
+      });
+      _ut.test('test_shiftExpression_missing_RHS_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_shiftExpression_missing_RHS_super);
+      });
+      _ut.test('test_shiftExpression_precedence_unary_left', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_shiftExpression_precedence_unary_left);
+      });
+      _ut.test('test_shiftExpression_precedence_unary_right', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_shiftExpression_precedence_unary_right);
+      });
+      _ut.test('test_shiftExpression_super', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_shiftExpression_super);
+      });
+      _ut.test('test_topLevelExternalFunction_extraSemicolon', () {
+        final __test = new RecoveryParserTest();
+        runJUnitTest(__test, __test.test_topLevelExternalFunction_extraSemicolon);
+      });
+    });
+  }
+}
+/**
+ * The class {@code SimpleParserTest} defines parser tests that test individual parsing method. The
+ * code fragments should be as minimal as possible in order to test the method, but should not test
+ * the interactions between the method under test and other methods.
+ * <p>
+ * More complex tests should be defined in the class {@link ComplexParserTest}.
+ */
+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);
+  }
+  void test_computeStringValue_emptyInterpolationPrefix() {
+    JUnitTestCase.assertEquals("", computeStringValue("'''"));
+  }
+  void test_computeStringValue_escape_b() {
+    JUnitTestCase.assertEquals("\b", computeStringValue("'\\b'"));
+  }
+  void test_computeStringValue_escape_f() {
+    JUnitTestCase.assertEquals("\f", computeStringValue("'\\f'"));
+  }
+  void test_computeStringValue_escape_n() {
+    JUnitTestCase.assertEquals("\n", computeStringValue("'\\n'"));
+  }
+  void test_computeStringValue_escape_notSpecial() {
+    JUnitTestCase.assertEquals(":", computeStringValue("'\\:'"));
+  }
+  void test_computeStringValue_escape_r() {
+    JUnitTestCase.assertEquals("\r", computeStringValue("'\\r'"));
+  }
+  void test_computeStringValue_escape_t() {
+    JUnitTestCase.assertEquals("\t", computeStringValue("'\\t'"));
+  }
+  void test_computeStringValue_escape_u_fixed() {
+    JUnitTestCase.assertEquals("\u4321", computeStringValue("'\\u4321'"));
+  }
+  void test_computeStringValue_escape_u_variable() {
+    JUnitTestCase.assertEquals("\u0123", computeStringValue("'\\u{123}'"));
+  }
+  void test_computeStringValue_escape_v() {
+    JUnitTestCase.assertEquals("\u000B", computeStringValue("'\\v'"));
+  }
+  void test_computeStringValue_escape_x() {
+    JUnitTestCase.assertEquals("\u00FF", computeStringValue("'\\xFF'"));
+  }
+  void test_computeStringValue_noEscape_single() {
+    JUnitTestCase.assertEquals("text", computeStringValue("'text'"));
+  }
+  void test_computeStringValue_noEscape_triple() {
+    JUnitTestCase.assertEquals("text", computeStringValue("'''text'''"));
+  }
+  void test_computeStringValue_raw_single() {
+    JUnitTestCase.assertEquals("text", computeStringValue("r'text'"));
+  }
+  void test_computeStringValue_raw_triple() {
+    JUnitTestCase.assertEquals("text", computeStringValue("r'''text'''"));
+  }
+  void test_computeStringValue_raw_withEscape() {
+    JUnitTestCase.assertEquals("two\\nlines", computeStringValue("r'two\\nlines'"));
+  }
+  void test_createSyntheticIdentifier() {
+    SimpleIdentifier identifier = createSyntheticIdentifier();
+    JUnitTestCase.assertTrue(identifier.isSynthetic());
+  }
+  void test_createSyntheticStringLiteral() {
+    SimpleStringLiteral literal = createSyntheticStringLiteral();
+    JUnitTestCase.assertTrue(literal.isSynthetic());
+  }
+  void test_isFunctionDeclaration_nameButNoReturn_block() {
+    JUnitTestCase.assertTrue(isFunctionDeclaration("f() {}"));
+  }
+  void test_isFunctionDeclaration_nameButNoReturn_expression() {
+    JUnitTestCase.assertTrue(isFunctionDeclaration("f() => e"));
+  }
+  void test_isFunctionDeclaration_normalReturn_block() {
+    JUnitTestCase.assertTrue(isFunctionDeclaration("C f() {}"));
+  }
+  void test_isFunctionDeclaration_normalReturn_expression() {
+    JUnitTestCase.assertTrue(isFunctionDeclaration("C f() => e"));
+  }
+  void test_isFunctionDeclaration_voidReturn_block() {
+    JUnitTestCase.assertTrue(isFunctionDeclaration("void f() {}"));
+  }
+  void test_isFunctionDeclaration_voidReturn_expression() {
+    JUnitTestCase.assertTrue(isFunctionDeclaration("void f() => e"));
+  }
+  void test_isFunctionExpression_false_noBody() {
+    JUnitTestCase.assertFalse(isFunctionExpression("f();"));
+  }
+  void test_isFunctionExpression_false_notParameters() {
+    JUnitTestCase.assertFalse(isFunctionExpression("(a + b) {"));
+  }
+  void test_isFunctionExpression_noName_block() {
+    JUnitTestCase.assertTrue(isFunctionExpression("() {}"));
+  }
+  void test_isFunctionExpression_noName_expression() {
+    JUnitTestCase.assertTrue(isFunctionExpression("() => e"));
+  }
+  void test_isFunctionExpression_parameter_multiple() {
+    JUnitTestCase.assertTrue(isFunctionExpression("(a, b) {}"));
+  }
+  void test_isFunctionExpression_parameter_named() {
+    JUnitTestCase.assertTrue(isFunctionExpression("({a}) {}"));
+  }
+  void test_isFunctionExpression_parameter_optional() {
+    JUnitTestCase.assertTrue(isFunctionExpression("([a]) {}"));
+  }
+  void test_isFunctionExpression_parameter_single() {
+    JUnitTestCase.assertTrue(isFunctionExpression("(a) {}"));
+  }
+  void test_isFunctionExpression_parameter_typed() {
+    JUnitTestCase.assertTrue(isFunctionExpression("(int a, int b) {}"));
+  }
+  void test_isInitializedVariableDeclaration_assignment() {
+    JUnitTestCase.assertFalse(isInitializedVariableDeclaration("a = null;"));
+  }
+  void test_isInitializedVariableDeclaration_comparison() {
+    JUnitTestCase.assertFalse(isInitializedVariableDeclaration("a < 0;"));
+  }
+  void test_isInitializedVariableDeclaration_conditional() {
+    JUnitTestCase.assertFalse(isInitializedVariableDeclaration("a == null ? init() : update();"));
+  }
+  void test_isInitializedVariableDeclaration_const_noType_initialized() {
+    JUnitTestCase.assertTrue(isInitializedVariableDeclaration("const a = 0;"));
+  }
+  void test_isInitializedVariableDeclaration_const_noType_uninitialized() {
+    JUnitTestCase.assertTrue(isInitializedVariableDeclaration("const a;"));
+  }
+  void test_isInitializedVariableDeclaration_const_simpleType_uninitialized() {
+    JUnitTestCase.assertTrue(isInitializedVariableDeclaration("const A a;"));
+  }
+  void test_isInitializedVariableDeclaration_final_noType_initialized() {
+    JUnitTestCase.assertTrue(isInitializedVariableDeclaration("final a = 0;"));
+  }
+  void test_isInitializedVariableDeclaration_final_noType_uninitialized() {
+    JUnitTestCase.assertTrue(isInitializedVariableDeclaration("final a;"));
+  }
+  void test_isInitializedVariableDeclaration_final_simpleType_initialized() {
+    JUnitTestCase.assertTrue(isInitializedVariableDeclaration("final A a = 0;"));
+  }
+  void test_isInitializedVariableDeclaration_functionDeclaration_typed() {
+    JUnitTestCase.assertFalse(isInitializedVariableDeclaration("A f() {};"));
+  }
+  void test_isInitializedVariableDeclaration_functionDeclaration_untyped() {
+    JUnitTestCase.assertFalse(isInitializedVariableDeclaration("f() {};"));
+  }
+  void test_isInitializedVariableDeclaration_noType_initialized() {
+    JUnitTestCase.assertTrue(isInitializedVariableDeclaration("var a = 0;"));
+  }
+  void test_isInitializedVariableDeclaration_noType_uninitialized() {
+    JUnitTestCase.assertTrue(isInitializedVariableDeclaration("var a;"));
+  }
+  void test_isInitializedVariableDeclaration_parameterizedType_initialized() {
+    JUnitTestCase.assertTrue(isInitializedVariableDeclaration("List<int> a = null;"));
+  }
+  void test_isInitializedVariableDeclaration_parameterizedType_uninitialized() {
+    JUnitTestCase.assertTrue(isInitializedVariableDeclaration("List<int> a;"));
+  }
+  void test_isInitializedVariableDeclaration_simpleType_initialized() {
+    JUnitTestCase.assertTrue(isInitializedVariableDeclaration("A a = 0;"));
+  }
+  void test_isInitializedVariableDeclaration_simpleType_uninitialized() {
+    JUnitTestCase.assertTrue(isInitializedVariableDeclaration("A a;"));
+  }
+  void test_isSwitchMember_case_labeled() {
+    JUnitTestCase.assertTrue(isSwitchMember("l1: l2: case"));
+  }
+  void test_isSwitchMember_case_unlabeled() {
+    JUnitTestCase.assertTrue(isSwitchMember("case"));
+  }
+  void test_isSwitchMember_default_labeled() {
+    JUnitTestCase.assertTrue(isSwitchMember("l1: l2: default"));
+  }
+  void test_isSwitchMember_default_unlabeled() {
+    JUnitTestCase.assertTrue(isSwitchMember("default"));
+  }
+  void test_isSwitchMember_false() {
+    JUnitTestCase.assertFalse(isSwitchMember("break;"));
+  }
+  void test_parseAdditiveExpression_normal() {
+    BinaryExpression expression = ParserTestCase.parse4("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", []);
+    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", []);
+    JUnitTestCase.assertNotNull(annotation.atSign);
+    JUnitTestCase.assertNotNull(annotation.name);
+    JUnitTestCase.assertNull(annotation.period);
+    JUnitTestCase.assertNull(annotation.constructorName);
+    JUnitTestCase.assertNull(annotation.arguments);
+  }
+  void test_parseAnnotation_n1_a() {
+    Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A(x,y)", []);
+    JUnitTestCase.assertNotNull(annotation.atSign);
+    JUnitTestCase.assertNotNull(annotation.name);
+    JUnitTestCase.assertNull(annotation.period);
+    JUnitTestCase.assertNull(annotation.constructorName);
+    JUnitTestCase.assertNotNull(annotation.arguments);
+  }
+  void test_parseAnnotation_n2() {
+    Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A.B", []);
+    JUnitTestCase.assertNotNull(annotation.atSign);
+    JUnitTestCase.assertNotNull(annotation.name);
+    JUnitTestCase.assertNull(annotation.period);
+    JUnitTestCase.assertNull(annotation.constructorName);
+    JUnitTestCase.assertNull(annotation.arguments);
+  }
+  void test_parseAnnotation_n2_a() {
+    Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A.B(x,y)", []);
+    JUnitTestCase.assertNotNull(annotation.atSign);
+    JUnitTestCase.assertNotNull(annotation.name);
+    JUnitTestCase.assertNull(annotation.period);
+    JUnitTestCase.assertNull(annotation.constructorName);
+    JUnitTestCase.assertNotNull(annotation.arguments);
+  }
+  void test_parseAnnotation_n3() {
+    Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A.B.C", []);
+    JUnitTestCase.assertNotNull(annotation.atSign);
+    JUnitTestCase.assertNotNull(annotation.name);
+    JUnitTestCase.assertNotNull(annotation.period);
+    JUnitTestCase.assertNotNull(annotation.constructorName);
+    JUnitTestCase.assertNull(annotation.arguments);
+  }
+  void test_parseAnnotation_n3_a() {
+    Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A.B.C(x,y)", []);
+    JUnitTestCase.assertNotNull(annotation.atSign);
+    JUnitTestCase.assertNotNull(annotation.name);
+    JUnitTestCase.assertNotNull(annotation.period);
+    JUnitTestCase.assertNotNull(annotation.constructorName);
+    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);
+    JUnitTestCase.assertNotNull(expression.expression);
+  }
+  void test_parseArgument_unnamed() {
+    String lexeme = "x";
+    SimpleIdentifier identifier = ParserTestCase.parse4("parseArgument", lexeme, []);
+    JUnitTestCase.assertEquals(lexeme, identifier.name);
+  }
+  void test_parseArgumentDefinitionTest() {
+    ArgumentDefinitionTest test = ParserTestCase.parse4("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);
+  }
+  void test_parseArgumentList_mixed() {
+    ArgumentList argumentList = ParserTestCase.parse4("parseArgumentList", "(w, x, y: y, z: z)", []);
+    NodeList<Expression> arguments7 = argumentList.arguments;
+    EngineTestCase.assertSize(4, arguments7);
+  }
+  void test_parseArgumentList_noNamed() {
+    ArgumentList argumentList = ParserTestCase.parse4("parseArgumentList", "(x, y, z)", []);
+    NodeList<Expression> arguments8 = argumentList.arguments;
+    EngineTestCase.assertSize(3, arguments8);
+  }
+  void test_parseArgumentList_onlyNamed() {
+    ArgumentList argumentList = ParserTestCase.parse4("parseArgumentList", "(x: x, y: y)", []);
+    NodeList<Expression> arguments9 = argumentList.arguments;
+    EngineTestCase.assertSize(2, arguments9);
+  }
+  void test_parseAssertStatement() {
+    AssertStatement statement = ParserTestCase.parse4("parseAssertStatement", "assert (x);", []);
+    JUnitTestCase.assertNotNull(statement.keyword);
+    JUnitTestCase.assertNotNull(statement.leftParenthesis);
+    JUnitTestCase.assertNotNull(statement.condition);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.semicolon);
+  }
+  void test_parseAssignableExpression_expression_args_dot() {
+    PropertyAccess propertyAccess = ParserTestCase.parse("parseAssignableExpression", <Object> [false], "(x)(y).z");
+    FunctionExpressionInvocation invocation = propertyAccess.target as FunctionExpressionInvocation;
+    JUnitTestCase.assertNotNull(invocation.function);
+    ArgumentList argumentList10 = invocation.argumentList;
+    JUnitTestCase.assertNotNull(argumentList10);
+    EngineTestCase.assertSize(1, argumentList10.arguments);
+    JUnitTestCase.assertNotNull(propertyAccess.operator);
+    JUnitTestCase.assertNotNull(propertyAccess.propertyName);
+  }
+  void test_parseAssignableExpression_expression_dot() {
+    PropertyAccess propertyAccess = ParserTestCase.parse("parseAssignableExpression", <Object> [false], "(x).y");
+    JUnitTestCase.assertNotNull(propertyAccess.target);
+    JUnitTestCase.assertNotNull(propertyAccess.operator);
+    JUnitTestCase.assertNotNull(propertyAccess.propertyName);
+  }
+  void test_parseAssignableExpression_expression_index() {
+    IndexExpression expression = ParserTestCase.parse("parseAssignableExpression", <Object> [false], "(x)[y]");
+    JUnitTestCase.assertNotNull(expression.array);
+    JUnitTestCase.assertNotNull(expression.leftBracket);
+    JUnitTestCase.assertNotNull(expression.index);
+    JUnitTestCase.assertNotNull(expression.rightBracket);
+  }
+  void test_parseAssignableExpression_identifier() {
+    SimpleIdentifier identifier = ParserTestCase.parse("parseAssignableExpression", <Object> [false], "x");
+    JUnitTestCase.assertNotNull(identifier);
+  }
+  void test_parseAssignableExpression_identifier_args_dot() {
+    PropertyAccess propertyAccess = ParserTestCase.parse("parseAssignableExpression", <Object> [false], "x(y).z");
+    MethodInvocation invocation = propertyAccess.target as MethodInvocation;
+    JUnitTestCase.assertEquals("x", invocation.methodName.name);
+    ArgumentList argumentList11 = invocation.argumentList;
+    JUnitTestCase.assertNotNull(argumentList11);
+    EngineTestCase.assertSize(1, argumentList11.arguments);
+    JUnitTestCase.assertNotNull(propertyAccess.operator);
+    JUnitTestCase.assertNotNull(propertyAccess.propertyName);
+  }
+  void test_parseAssignableExpression_identifier_dot() {
+    PropertyAccess propertyAccess = ParserTestCase.parse("parseAssignableExpression", <Object> [false], "x.y");
+    JUnitTestCase.assertNotNull(propertyAccess.target);
+    JUnitTestCase.assertNotNull(propertyAccess.operator);
+    JUnitTestCase.assertNotNull(propertyAccess.propertyName);
+  }
+  void test_parseAssignableExpression_identifier_index() {
+    IndexExpression expression = ParserTestCase.parse("parseAssignableExpression", <Object> [false], "x[y]");
+    JUnitTestCase.assertNotNull(expression.array);
+    JUnitTestCase.assertNotNull(expression.leftBracket);
+    JUnitTestCase.assertNotNull(expression.index);
+    JUnitTestCase.assertNotNull(expression.rightBracket);
+  }
+  void test_parseAssignableExpression_super_dot() {
+    PropertyAccess propertyAccess = ParserTestCase.parse("parseAssignableExpression", <Object> [false], "super.y");
+    EngineTestCase.assertInstanceOf(SuperExpression, propertyAccess.target);
+    JUnitTestCase.assertNotNull(propertyAccess.operator);
+    JUnitTestCase.assertNotNull(propertyAccess.propertyName);
+  }
+  void test_parseAssignableExpression_super_index() {
+    IndexExpression expression = ParserTestCase.parse("parseAssignableExpression", <Object> [false], "super[y]");
+    EngineTestCase.assertInstanceOf(SuperExpression, expression.array);
+    JUnitTestCase.assertNotNull(expression.leftBracket);
+    JUnitTestCase.assertNotNull(expression.index);
+    JUnitTestCase.assertNotNull(expression.rightBracket);
+  }
+  void test_parseAssignableSelector_dot() {
+    PropertyAccess selector = ParserTestCase.parse("parseAssignableSelector", <Object> [null, true], ".x");
+    JUnitTestCase.assertNotNull(selector.operator);
+    JUnitTestCase.assertNotNull(selector.propertyName);
+  }
+  void test_parseAssignableSelector_index() {
+    IndexExpression selector = ParserTestCase.parse("parseAssignableSelector", <Object> [null, true], "[x]");
+    JUnitTestCase.assertNotNull(selector.leftBracket);
+    JUnitTestCase.assertNotNull(selector.index);
+    JUnitTestCase.assertNotNull(selector.rightBracket);
+  }
+  void test_parseAssignableSelector_none() {
+    SimpleIdentifier selector = ParserTestCase.parse("parseAssignableSelector", <Object> [new SimpleIdentifier(null), true], ";");
+    JUnitTestCase.assertNotNull(selector);
+  }
+  void test_parseBitwiseAndExpression_normal() {
+    BinaryExpression expression = ParserTestCase.parse4("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", []);
+    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", []);
+    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", []);
+    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", []);
+    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", []);
+    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", "{}", []);
+    JUnitTestCase.assertNotNull(block.leftBracket);
+    EngineTestCase.assertSize(0, block.statements);
+    JUnitTestCase.assertNotNull(block.rightBracket);
+  }
+  void test_parseBlock_nonEmpty() {
+    Block block = ParserTestCase.parse4("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;", []);
+    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]);
+    JUnitTestCase.assertNotNull(statement.keyword);
+    JUnitTestCase.assertNull(statement.label);
+    JUnitTestCase.assertNotNull(statement.semicolon);
+  }
+  void test_parseCascadeSection_i() {
+    IndexExpression section = ParserTestCase.parse4("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)", []);
+    EngineTestCase.assertInstanceOf(IndexExpression, section.function);
+    JUnitTestCase.assertNotNull(section.argumentList);
+  }
+  void test_parseCascadeSection_p() {
+    PropertyAccess section = ParserTestCase.parse4("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", []);
+    JUnitTestCase.assertNotNull(section.leftHandSide);
+    JUnitTestCase.assertNotNull(section.operator);
+    JUnitTestCase.assertNotNull(section.rightHandSide);
+  }
+  void test_parseCascadeSection_p_builtIn() {
+    PropertyAccess section = ParserTestCase.parse4("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)", []);
+    JUnitTestCase.assertNull(section.target);
+    JUnitTestCase.assertNotNull(section.period);
+    JUnitTestCase.assertNotNull(section.methodName);
+    JUnitTestCase.assertNotNull(section.argumentList);
+    EngineTestCase.assertSize(1, section.argumentList.arguments);
+  }
+  void test_parseCascadeSection_paa() {
+    FunctionExpressionInvocation section = ParserTestCase.parse4("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)", []);
+    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", []);
+    JUnitTestCase.assertNotNull(section.target);
+    JUnitTestCase.assertNotNull(section.operator);
+    JUnitTestCase.assertNotNull(section.propertyName);
+  }
+  void test_parseClassDeclaration_abstract() {
+    ClassDeclaration declaration = ParserTestCase.parse("parseClassDeclaration", <Object> [emptyCommentAndMetadata(), TokenFactory.token(Keyword.ABSTRACT)], "class A {}");
+    JUnitTestCase.assertNull(declaration.documentationComment);
+    JUnitTestCase.assertNotNull(declaration.abstractKeyword);
+    JUnitTestCase.assertNull(declaration.extendsClause);
+    JUnitTestCase.assertNull(declaration.implementsClause);
+    JUnitTestCase.assertNotNull(declaration.classKeyword);
+    JUnitTestCase.assertNotNull(declaration.leftBracket);
+    JUnitTestCase.assertNotNull(declaration.name);
+    EngineTestCase.assertSize(0, declaration.members);
+    JUnitTestCase.assertNotNull(declaration.rightBracket);
+    JUnitTestCase.assertNull(declaration.typeParameters);
+  }
+  void test_parseClassDeclaration_empty() {
+    ClassDeclaration declaration = ParserTestCase.parse("parseClassDeclaration", <Object> [emptyCommentAndMetadata(), null], "class A {}");
+    JUnitTestCase.assertNull(declaration.documentationComment);
+    JUnitTestCase.assertNull(declaration.abstractKeyword);
+    JUnitTestCase.assertNull(declaration.extendsClause);
+    JUnitTestCase.assertNull(declaration.implementsClause);
+    JUnitTestCase.assertNotNull(declaration.classKeyword);
+    JUnitTestCase.assertNotNull(declaration.leftBracket);
+    JUnitTestCase.assertNotNull(declaration.name);
+    EngineTestCase.assertSize(0, declaration.members);
+    JUnitTestCase.assertNotNull(declaration.rightBracket);
+    JUnitTestCase.assertNull(declaration.typeParameters);
+  }
+  void test_parseClassDeclaration_extends() {
+    ClassDeclaration declaration = ParserTestCase.parse("parseClassDeclaration", <Object> [emptyCommentAndMetadata(), null], "class A extends B {}");
+    JUnitTestCase.assertNull(declaration.documentationComment);
+    JUnitTestCase.assertNull(declaration.abstractKeyword);
+    JUnitTestCase.assertNotNull(declaration.extendsClause);
+    JUnitTestCase.assertNull(declaration.implementsClause);
+    JUnitTestCase.assertNotNull(declaration.classKeyword);
+    JUnitTestCase.assertNotNull(declaration.leftBracket);
+    JUnitTestCase.assertNotNull(declaration.name);
+    EngineTestCase.assertSize(0, declaration.members);
+    JUnitTestCase.assertNotNull(declaration.rightBracket);
+    JUnitTestCase.assertNull(declaration.typeParameters);
+  }
+  void test_parseClassDeclaration_extendsAndImplements() {
+    ClassDeclaration declaration = ParserTestCase.parse("parseClassDeclaration", <Object> [emptyCommentAndMetadata(), null], "class A extends B implements C {}");
+    JUnitTestCase.assertNull(declaration.documentationComment);
+    JUnitTestCase.assertNull(declaration.abstractKeyword);
+    JUnitTestCase.assertNotNull(declaration.extendsClause);
+    JUnitTestCase.assertNotNull(declaration.implementsClause);
+    JUnitTestCase.assertNotNull(declaration.classKeyword);
+    JUnitTestCase.assertNotNull(declaration.leftBracket);
+    JUnitTestCase.assertNotNull(declaration.name);
+    EngineTestCase.assertSize(0, declaration.members);
+    JUnitTestCase.assertNotNull(declaration.rightBracket);
+    JUnitTestCase.assertNull(declaration.typeParameters);
+  }
+  void test_parseClassDeclaration_extendsAndWith() {
+    ClassDeclaration declaration = ParserTestCase.parse("parseClassDeclaration", <Object> [emptyCommentAndMetadata(), null], "class A extends B with C {}");
+    JUnitTestCase.assertNull(declaration.documentationComment);
+    JUnitTestCase.assertNull(declaration.abstractKeyword);
+    JUnitTestCase.assertNotNull(declaration.classKeyword);
+    JUnitTestCase.assertNotNull(declaration.name);
+    JUnitTestCase.assertNull(declaration.typeParameters);
+    JUnitTestCase.assertNotNull(declaration.extendsClause);
+    JUnitTestCase.assertNotNull(declaration.withClause);
+    JUnitTestCase.assertNull(declaration.implementsClause);
+    JUnitTestCase.assertNotNull(declaration.leftBracket);
+    EngineTestCase.assertSize(0, declaration.members);
+    JUnitTestCase.assertNotNull(declaration.rightBracket);
+  }
+  void test_parseClassDeclaration_extendsAndWithAndImplements() {
+    ClassDeclaration declaration = ParserTestCase.parse("parseClassDeclaration", <Object> [emptyCommentAndMetadata(), null], "class A extends B with C implements D {}");
+    JUnitTestCase.assertNull(declaration.documentationComment);
+    JUnitTestCase.assertNull(declaration.abstractKeyword);
+    JUnitTestCase.assertNotNull(declaration.classKeyword);
+    JUnitTestCase.assertNotNull(declaration.name);
+    JUnitTestCase.assertNull(declaration.typeParameters);
+    JUnitTestCase.assertNotNull(declaration.extendsClause);
+    JUnitTestCase.assertNotNull(declaration.withClause);
+    JUnitTestCase.assertNotNull(declaration.implementsClause);
+    JUnitTestCase.assertNotNull(declaration.leftBracket);
+    EngineTestCase.assertSize(0, declaration.members);
+    JUnitTestCase.assertNotNull(declaration.rightBracket);
+  }
+  void test_parseClassDeclaration_implements() {
+    ClassDeclaration declaration = ParserTestCase.parse("parseClassDeclaration", <Object> [emptyCommentAndMetadata(), null], "class A implements C {}");
+    JUnitTestCase.assertNull(declaration.documentationComment);
+    JUnitTestCase.assertNull(declaration.abstractKeyword);
+    JUnitTestCase.assertNull(declaration.extendsClause);
+    JUnitTestCase.assertNotNull(declaration.implementsClause);
+    JUnitTestCase.assertNotNull(declaration.classKeyword);
+    JUnitTestCase.assertNotNull(declaration.leftBracket);
+    JUnitTestCase.assertNotNull(declaration.name);
+    EngineTestCase.assertSize(0, declaration.members);
+    JUnitTestCase.assertNotNull(declaration.rightBracket);
+    JUnitTestCase.assertNull(declaration.typeParameters);
+  }
+  void test_parseClassDeclaration_nonEmpty() {
+    ClassDeclaration declaration = ParserTestCase.parse("parseClassDeclaration", <Object> [emptyCommentAndMetadata(), null], "class A {var f;}");
+    JUnitTestCase.assertNull(declaration.documentationComment);
+    JUnitTestCase.assertNull(declaration.abstractKeyword);
+    JUnitTestCase.assertNull(declaration.extendsClause);
+    JUnitTestCase.assertNull(declaration.implementsClause);
+    JUnitTestCase.assertNotNull(declaration.classKeyword);
+    JUnitTestCase.assertNotNull(declaration.leftBracket);
+    JUnitTestCase.assertNotNull(declaration.name);
+    EngineTestCase.assertSize(1, declaration.members);
+    JUnitTestCase.assertNotNull(declaration.rightBracket);
+    JUnitTestCase.assertNull(declaration.typeParameters);
+  }
+  void test_parseClassDeclaration_typeParameters() {
+    ClassDeclaration declaration = ParserTestCase.parse("parseClassDeclaration", <Object> [emptyCommentAndMetadata(), null], "class A<B> {}");
+    JUnitTestCase.assertNull(declaration.documentationComment);
+    JUnitTestCase.assertNull(declaration.abstractKeyword);
+    JUnitTestCase.assertNull(declaration.extendsClause);
+    JUnitTestCase.assertNull(declaration.implementsClause);
+    JUnitTestCase.assertNotNull(declaration.classKeyword);
+    JUnitTestCase.assertNotNull(declaration.leftBracket);
+    JUnitTestCase.assertNotNull(declaration.name);
+    EngineTestCase.assertSize(0, declaration.members);
+    JUnitTestCase.assertNotNull(declaration.rightBracket);
+    JUnitTestCase.assertNotNull(declaration.typeParameters);
+    EngineTestCase.assertSize(1, declaration.typeParameters.typeParameters);
+  }
+  void test_parseClassMember_constructor_withInitializers() {
+    ConstructorDeclaration constructor = ParserTestCase.parse("parseClassMember", <Object> ["C"], "C(_, _\$, this.__) : _a = _ + _\$ {}");
+    JUnitTestCase.assertNotNull(constructor.body);
+    JUnitTestCase.assertNotNull(constructor.separator);
+    JUnitTestCase.assertNull(constructor.externalKeyword);
+    JUnitTestCase.assertNull(constructor.constKeyword);
+    JUnitTestCase.assertNull(constructor.factoryKeyword);
+    JUnitTestCase.assertNull(constructor.name);
+    JUnitTestCase.assertNotNull(constructor.parameters);
+    JUnitTestCase.assertNull(constructor.period);
+    JUnitTestCase.assertNotNull(constructor.returnType);
+    EngineTestCase.assertSize(1, constructor.initializers);
+  }
+  void test_parseClassMember_field_instance_prefixedType() {
+    FieldDeclaration field = ParserTestCase.parse("parseClassMember", <Object> ["C"], "p.A f;");
+    JUnitTestCase.assertNull(field.documentationComment);
+    EngineTestCase.assertSize(0, field.metadata);
+    JUnitTestCase.assertNull(field.keyword);
+    VariableDeclarationList list = field.fields;
+    JUnitTestCase.assertNotNull(list);
+    NodeList<VariableDeclaration> variables6 = list.variables;
+    EngineTestCase.assertSize(1, variables6);
+    VariableDeclaration variable = variables6[0];
+    JUnitTestCase.assertNotNull(variable.name);
+  }
+  void test_parseClassMember_field_namedGet() {
+    FieldDeclaration field = ParserTestCase.parse("parseClassMember", <Object> ["C"], "var get;");
+    JUnitTestCase.assertNull(field.documentationComment);
+    EngineTestCase.assertSize(0, field.metadata);
+    JUnitTestCase.assertNull(field.keyword);
+    VariableDeclarationList list = field.fields;
+    JUnitTestCase.assertNotNull(list);
+    NodeList<VariableDeclaration> variables7 = list.variables;
+    EngineTestCase.assertSize(1, variables7);
+    VariableDeclaration variable = variables7[0];
+    JUnitTestCase.assertNotNull(variable.name);
+  }
+  void test_parseClassMember_field_namedOperator() {
+    FieldDeclaration field = ParserTestCase.parse("parseClassMember", <Object> ["C"], "var operator;");
+    JUnitTestCase.assertNull(field.documentationComment);
+    EngineTestCase.assertSize(0, field.metadata);
+    JUnitTestCase.assertNull(field.keyword);
+    VariableDeclarationList list = field.fields;
+    JUnitTestCase.assertNotNull(list);
+    NodeList<VariableDeclaration> variables8 = list.variables;
+    EngineTestCase.assertSize(1, variables8);
+    VariableDeclaration variable = variables8[0];
+    JUnitTestCase.assertNotNull(variable.name);
+  }
+  void test_parseClassMember_field_namedSet() {
+    FieldDeclaration field = ParserTestCase.parse("parseClassMember", <Object> ["C"], "var set;");
+    JUnitTestCase.assertNull(field.documentationComment);
+    EngineTestCase.assertSize(0, field.metadata);
+    JUnitTestCase.assertNull(field.keyword);
+    VariableDeclarationList list = field.fields;
+    JUnitTestCase.assertNotNull(list);
+    NodeList<VariableDeclaration> variables9 = list.variables;
+    EngineTestCase.assertSize(1, variables9);
+    VariableDeclaration variable = variables9[0];
+    JUnitTestCase.assertNotNull(variable.name);
+  }
+  void test_parseClassMember_getter_void() {
+    MethodDeclaration method = ParserTestCase.parse("parseClassMember", <Object> ["C"], "void get g {}");
+    JUnitTestCase.assertNull(method.documentationComment);
+    JUnitTestCase.assertNull(method.externalKeyword);
+    JUnitTestCase.assertNull(method.modifierKeyword);
+    JUnitTestCase.assertNotNull(method.propertyKeyword);
+    JUnitTestCase.assertNotNull(method.returnType);
+    JUnitTestCase.assertNotNull(method.name);
+    JUnitTestCase.assertNull(method.operatorKeyword);
+    JUnitTestCase.assertNotNull(method.body);
+  }
+  void test_parseClassMember_method_external() {
+    MethodDeclaration method = ParserTestCase.parse("parseClassMember", <Object> ["C"], "external m();");
+    JUnitTestCase.assertNotNull(method.body);
+    JUnitTestCase.assertNull(method.documentationComment);
+    JUnitTestCase.assertNotNull(method.externalKeyword);
+    JUnitTestCase.assertNull(method.modifierKeyword);
+    JUnitTestCase.assertNotNull(method.name);
+    JUnitTestCase.assertNull(method.operatorKeyword);
+    JUnitTestCase.assertNotNull(method.parameters);
+    JUnitTestCase.assertNull(method.propertyKeyword);
+    JUnitTestCase.assertNull(method.returnType);
+  }
+  void test_parseClassMember_method_external_withTypeAndArgs() {
+    MethodDeclaration method = ParserTestCase.parse("parseClassMember", <Object> ["C"], "external int m(int a);");
+    JUnitTestCase.assertNotNull(method.body);
+    JUnitTestCase.assertNull(method.documentationComment);
+    JUnitTestCase.assertNotNull(method.externalKeyword);
+    JUnitTestCase.assertNull(method.modifierKeyword);
+    JUnitTestCase.assertNotNull(method.name);
+    JUnitTestCase.assertNull(method.operatorKeyword);
+    JUnitTestCase.assertNotNull(method.parameters);
+    JUnitTestCase.assertNull(method.propertyKeyword);
+    JUnitTestCase.assertNotNull(method.returnType);
+  }
+  void test_parseClassMember_method_get_noType() {
+    MethodDeclaration method = ParserTestCase.parse("parseClassMember", <Object> ["C"], "get() {}");
+    JUnitTestCase.assertNull(method.documentationComment);
+    JUnitTestCase.assertNull(method.externalKeyword);
+    JUnitTestCase.assertNull(method.modifierKeyword);
+    JUnitTestCase.assertNull(method.propertyKeyword);
+    JUnitTestCase.assertNull(method.returnType);
+    JUnitTestCase.assertNotNull(method.name);
+    JUnitTestCase.assertNull(method.operatorKeyword);
+    JUnitTestCase.assertNotNull(method.parameters);
+    JUnitTestCase.assertNotNull(method.body);
+  }
+  void test_parseClassMember_method_get_type() {
+    MethodDeclaration method = ParserTestCase.parse("parseClassMember", <Object> ["C"], "int get() {}");
+    JUnitTestCase.assertNull(method.documentationComment);
+    JUnitTestCase.assertNull(method.externalKeyword);
+    JUnitTestCase.assertNull(method.modifierKeyword);
+    JUnitTestCase.assertNull(method.propertyKeyword);
+    JUnitTestCase.assertNotNull(method.returnType);
+    JUnitTestCase.assertNotNull(method.name);
+    JUnitTestCase.assertNull(method.operatorKeyword);
+    JUnitTestCase.assertNotNull(method.parameters);
+    JUnitTestCase.assertNotNull(method.body);
+  }
+  void test_parseClassMember_method_get_void() {
+    MethodDeclaration method = ParserTestCase.parse("parseClassMember", <Object> ["C"], "void get() {}");
+    JUnitTestCase.assertNull(method.documentationComment);
+    JUnitTestCase.assertNull(method.externalKeyword);
+    JUnitTestCase.assertNull(method.modifierKeyword);
+    JUnitTestCase.assertNull(method.propertyKeyword);
+    JUnitTestCase.assertNotNull(method.returnType);
+    JUnitTestCase.assertNotNull(method.name);
+    JUnitTestCase.assertNull(method.operatorKeyword);
+    JUnitTestCase.assertNotNull(method.parameters);
+    JUnitTestCase.assertNotNull(method.body);
+  }
+  void test_parseClassMember_method_operator_noType() {
+    MethodDeclaration method = ParserTestCase.parse("parseClassMember", <Object> ["C"], "operator() {}");
+    JUnitTestCase.assertNull(method.documentationComment);
+    JUnitTestCase.assertNull(method.externalKeyword);
+    JUnitTestCase.assertNull(method.modifierKeyword);
+    JUnitTestCase.assertNull(method.propertyKeyword);
+    JUnitTestCase.assertNull(method.returnType);
+    JUnitTestCase.assertNotNull(method.name);
+    JUnitTestCase.assertNull(method.operatorKeyword);
+    JUnitTestCase.assertNotNull(method.parameters);
+    JUnitTestCase.assertNotNull(method.body);
+  }
+  void test_parseClassMember_method_operator_type() {
+    MethodDeclaration method = ParserTestCase.parse("parseClassMember", <Object> ["C"], "int operator() {}");
+    JUnitTestCase.assertNull(method.documentationComment);
+    JUnitTestCase.assertNull(method.externalKeyword);
+    JUnitTestCase.assertNull(method.modifierKeyword);
+    JUnitTestCase.assertNull(method.propertyKeyword);
+    JUnitTestCase.assertNotNull(method.returnType);
+    JUnitTestCase.assertNotNull(method.name);
+    JUnitTestCase.assertNull(method.operatorKeyword);
+    JUnitTestCase.assertNotNull(method.parameters);
+    JUnitTestCase.assertNotNull(method.body);
+  }
+  void test_parseClassMember_method_operator_void() {
+    MethodDeclaration method = ParserTestCase.parse("parseClassMember", <Object> ["C"], "void operator() {}");
+    JUnitTestCase.assertNull(method.documentationComment);
+    JUnitTestCase.assertNull(method.externalKeyword);
+    JUnitTestCase.assertNull(method.modifierKeyword);
+    JUnitTestCase.assertNull(method.propertyKeyword);
+    JUnitTestCase.assertNotNull(method.returnType);
+    JUnitTestCase.assertNotNull(method.name);
+    JUnitTestCase.assertNull(method.operatorKeyword);
+    JUnitTestCase.assertNotNull(method.parameters);
+    JUnitTestCase.assertNotNull(method.body);
+  }
+  void test_parseClassMember_method_returnType_parameterized() {
+    MethodDeclaration method = ParserTestCase.parse("parseClassMember", <Object> ["C"], "p.A m() {}");
+    JUnitTestCase.assertNull(method.documentationComment);
+    JUnitTestCase.assertNull(method.externalKeyword);
+    JUnitTestCase.assertNull(method.modifierKeyword);
+    JUnitTestCase.assertNull(method.propertyKeyword);
+    JUnitTestCase.assertNotNull(method.returnType);
+    JUnitTestCase.assertNotNull(method.name);
+    JUnitTestCase.assertNull(method.operatorKeyword);
+    JUnitTestCase.assertNotNull(method.parameters);
+    JUnitTestCase.assertNotNull(method.body);
+  }
+  void test_parseClassMember_method_set_noType() {
+    MethodDeclaration method = ParserTestCase.parse("parseClassMember", <Object> ["C"], "set() {}");
+    JUnitTestCase.assertNull(method.documentationComment);
+    JUnitTestCase.assertNull(method.externalKeyword);
+    JUnitTestCase.assertNull(method.modifierKeyword);
+    JUnitTestCase.assertNull(method.propertyKeyword);
+    JUnitTestCase.assertNull(method.returnType);
+    JUnitTestCase.assertNotNull(method.name);
+    JUnitTestCase.assertNull(method.operatorKeyword);
+    JUnitTestCase.assertNotNull(method.parameters);
+    JUnitTestCase.assertNotNull(method.body);
+  }
+  void test_parseClassMember_method_set_type() {
+    MethodDeclaration method = ParserTestCase.parse("parseClassMember", <Object> ["C"], "int set() {}");
+    JUnitTestCase.assertNull(method.documentationComment);
+    JUnitTestCase.assertNull(method.externalKeyword);
+    JUnitTestCase.assertNull(method.modifierKeyword);
+    JUnitTestCase.assertNull(method.propertyKeyword);
+    JUnitTestCase.assertNotNull(method.returnType);
+    JUnitTestCase.assertNotNull(method.name);
+    JUnitTestCase.assertNull(method.operatorKeyword);
+    JUnitTestCase.assertNotNull(method.parameters);
+    JUnitTestCase.assertNotNull(method.body);
+  }
+  void test_parseClassMember_method_set_void() {
+    MethodDeclaration method = ParserTestCase.parse("parseClassMember", <Object> ["C"], "void set() {}");
+    JUnitTestCase.assertNull(method.documentationComment);
+    JUnitTestCase.assertNull(method.externalKeyword);
+    JUnitTestCase.assertNull(method.modifierKeyword);
+    JUnitTestCase.assertNull(method.propertyKeyword);
+    JUnitTestCase.assertNotNull(method.returnType);
+    JUnitTestCase.assertNotNull(method.name);
+    JUnitTestCase.assertNull(method.operatorKeyword);
+    JUnitTestCase.assertNotNull(method.parameters);
+    JUnitTestCase.assertNotNull(method.body);
+  }
+  void test_parseClassMember_operator_index() {
+    MethodDeclaration method = ParserTestCase.parse("parseClassMember", <Object> ["C"], "int operator [](int i) {}");
+    JUnitTestCase.assertNull(method.documentationComment);
+    JUnitTestCase.assertNull(method.externalKeyword);
+    JUnitTestCase.assertNull(method.modifierKeyword);
+    JUnitTestCase.assertNull(method.propertyKeyword);
+    JUnitTestCase.assertNotNull(method.returnType);
+    JUnitTestCase.assertNotNull(method.name);
+    JUnitTestCase.assertNotNull(method.operatorKeyword);
+    JUnitTestCase.assertNotNull(method.parameters);
+    JUnitTestCase.assertNotNull(method.body);
+  }
+  void test_parseClassMember_operator_indexAssign() {
+    MethodDeclaration method = ParserTestCase.parse("parseClassMember", <Object> ["C"], "int operator []=(int i) {}");
+    JUnitTestCase.assertNull(method.documentationComment);
+    JUnitTestCase.assertNull(method.externalKeyword);
+    JUnitTestCase.assertNull(method.modifierKeyword);
+    JUnitTestCase.assertNull(method.propertyKeyword);
+    JUnitTestCase.assertNotNull(method.returnType);
+    JUnitTestCase.assertNotNull(method.name);
+    JUnitTestCase.assertNotNull(method.operatorKeyword);
+    JUnitTestCase.assertNotNull(method.parameters);
+    JUnitTestCase.assertNotNull(method.body);
+  }
+  void test_parseClassMember_redirectingFactory_const() {
+    ConstructorDeclaration constructor = ParserTestCase.parse("parseClassMember", <Object> ["C"], "const factory C() = B;");
+    JUnitTestCase.assertNull(constructor.externalKeyword);
+    JUnitTestCase.assertNotNull(constructor.constKeyword);
+    JUnitTestCase.assertNotNull(constructor.factoryKeyword);
+    JUnitTestCase.assertNotNull(constructor.returnType);
+    JUnitTestCase.assertNull(constructor.period);
+    JUnitTestCase.assertNull(constructor.name);
+    JUnitTestCase.assertNotNull(constructor.parameters);
+    JUnitTestCase.assertNotNull(constructor.separator);
+    EngineTestCase.assertSize(0, constructor.initializers);
+    JUnitTestCase.assertNotNull(constructor.redirectedConstructor);
+    JUnitTestCase.assertNotNull(constructor.body);
+  }
+  void test_parseClassMember_redirectingFactory_nonConst() {
+    ConstructorDeclaration constructor = ParserTestCase.parse("parseClassMember", <Object> ["C"], "factory C() = B;");
+    JUnitTestCase.assertNull(constructor.externalKeyword);
+    JUnitTestCase.assertNull(constructor.constKeyword);
+    JUnitTestCase.assertNotNull(constructor.factoryKeyword);
+    JUnitTestCase.assertNotNull(constructor.returnType);
+    JUnitTestCase.assertNull(constructor.period);
+    JUnitTestCase.assertNull(constructor.name);
+    JUnitTestCase.assertNotNull(constructor.parameters);
+    JUnitTestCase.assertNotNull(constructor.separator);
+    EngineTestCase.assertSize(0, constructor.initializers);
+    JUnitTestCase.assertNotNull(constructor.redirectedConstructor);
+    JUnitTestCase.assertNotNull(constructor.body);
+  }
+  void test_parseCombinators_h() {
+    List<Combinator> combinators = ParserTestCase.parse4("parseCombinators", "hide a;", []);
+    EngineTestCase.assertSize(1, combinators);
+    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;", []);
+    EngineTestCase.assertSize(2, combinators);
+    HideCombinator hideCombinator = combinators[0] as HideCombinator;
+    JUnitTestCase.assertNotNull(hideCombinator);
+    JUnitTestCase.assertNotNull(hideCombinator.keyword);
+    EngineTestCase.assertSize(1, hideCombinator.hiddenNames);
+    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;", []);
+    EngineTestCase.assertSize(4, combinators);
+  }
+  void test_parseCombinators_s() {
+    List<Combinator> combinators = ParserTestCase.parse4("parseCombinators", "show a;", []);
+    EngineTestCase.assertSize(1, combinators);
+    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", []);
+    JUnitTestCase.assertNotNull(commentAndMetadata.comment);
+    EngineTestCase.assertSize(0, commentAndMetadata.metadata);
+  }
+  void test_parseCommentAndMetadata_cmc() {
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("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", []);
+    JUnitTestCase.assertNotNull(commentAndMetadata.comment);
+    EngineTestCase.assertSize(2, commentAndMetadata.metadata);
+  }
+  void test_parseCommentAndMetadata_cmm() {
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("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", []);
+    JUnitTestCase.assertNull(commentAndMetadata.comment);
+    EngineTestCase.assertSize(1, commentAndMetadata.metadata);
+  }
+  void test_parseCommentAndMetadata_mcm() {
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("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", []);
+    JUnitTestCase.assertNotNull(commentAndMetadata.comment);
+    EngineTestCase.assertSize(2, commentAndMetadata.metadata);
+  }
+  void test_parseCommentAndMetadata_mm() {
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("parseCommentAndMetadata", "@A @B(x) void", []);
+    JUnitTestCase.assertNull(commentAndMetadata.comment);
+    EngineTestCase.assertSize(2, commentAndMetadata.metadata);
+  }
+  void test_parseCommentAndMetadata_none() {
+    CommentAndMetadata commentAndMetadata = ParserTestCase.parse4("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);
+    JUnitTestCase.assertNotNull(prefixedIdentifier.period);
+    SimpleIdentifier identifier9 = prefixedIdentifier.identifier;
+    JUnitTestCase.assertNotNull(identifier9.token);
+    JUnitTestCase.assertEquals("b", identifier9.name);
+    JUnitTestCase.assertEquals(13, identifier9.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);
+  }
+  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);
+    JUnitTestCase.assertNotNull(prefixedIdentifier.period);
+    SimpleIdentifier identifier11 = prefixedIdentifier.identifier;
+    JUnitTestCase.assertNotNull(identifier11.token);
+    JUnitTestCase.assertEquals("b", identifier11.name);
+    JUnitTestCase.assertEquals(9, identifier11.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);
+  }
+  void test_parseCommentReferences_multiLine() {
+    List<Token> tokens = <Token> [new StringToken(TokenType.MULTI_LINE_COMMENT, "/** xxx [a] yyy [b] zzz */", 3)];
+    List<CommentReference> references = ParserTestCase.parse("parseCommentReferences", <Object> [tokens], "");
+    EngineTestCase.assertSize(2, references);
+    CommentReference reference = references[0];
+    JUnitTestCase.assertNotNull(reference);
+    JUnitTestCase.assertNotNull(reference.identifier);
+    JUnitTestCase.assertEquals(12, reference.offset);
+    reference = references[1];
+    JUnitTestCase.assertNotNull(reference);
+    JUnitTestCase.assertNotNull(reference.identifier);
+    JUnitTestCase.assertEquals(20, reference.offset);
+  }
+  void test_parseCommentReferences_singleLine() {
+    List<Token> tokens = <Token> [new StringToken(TokenType.SINGLE_LINE_COMMENT, "/// xxx [a] yyy [b] zzz", 3), new StringToken(TokenType.SINGLE_LINE_COMMENT, "/// x [c]", 28)];
+    List<CommentReference> references = ParserTestCase.parse("parseCommentReferences", <Object> [tokens], "");
+    EngineTestCase.assertSize(3, references);
+    CommentReference reference = references[0];
+    JUnitTestCase.assertNotNull(reference);
+    JUnitTestCase.assertNotNull(reference.identifier);
+    JUnitTestCase.assertEquals(12, reference.offset);
+    reference = references[1];
+    JUnitTestCase.assertNotNull(reference);
+    JUnitTestCase.assertNotNull(reference.identifier);
+    JUnitTestCase.assertEquals(20, reference.offset);
+    reference = references[2];
+    JUnitTestCase.assertNotNull(reference);
+    JUnitTestCase.assertNotNull(reference.identifier);
+    JUnitTestCase.assertEquals(35, reference.offset);
+  }
+  void test_parseCompilationUnit_directives_multiple() {
+    CompilationUnit unit = ParserTestCase.parse4("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;", []);
+    JUnitTestCase.assertNull(unit.scriptTag);
+    EngineTestCase.assertSize(1, unit.directives);
+    EngineTestCase.assertSize(0, unit.declarations);
+  }
+  void test_parseCompilationUnit_empty() {
+    CompilationUnit unit = ParserTestCase.parse4("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", []);
+    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 {}", []);
+    JUnitTestCase.assertNull(unit.scriptTag);
+    EngineTestCase.assertSize(0, unit.directives);
+    EngineTestCase.assertSize(1, unit.declarations);
+  }
+  void test_parseCompilationUnitMember_class() {
+    ClassDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "class A {}");
+    JUnitTestCase.assertEquals("A", declaration.name.name);
+    EngineTestCase.assertSize(0, declaration.members);
+  }
+  void test_parseCompilationUnitMember_constVariable() {
+    TopLevelVariableDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "const int x = 0;");
+    JUnitTestCase.assertNotNull(declaration.semicolon);
+    JUnitTestCase.assertNotNull(declaration.variables);
+  }
+  void test_parseCompilationUnitMember_finalVariable() {
+    TopLevelVariableDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "final x = 0;");
+    JUnitTestCase.assertNotNull(declaration.semicolon);
+    JUnitTestCase.assertNotNull(declaration.variables);
+  }
+  void test_parseCompilationUnitMember_function_external_noType() {
+    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "external f()");
+    JUnitTestCase.assertNotNull(declaration.externalKeyword);
+    JUnitTestCase.assertNotNull(declaration.functionExpression);
+    JUnitTestCase.assertNull(declaration.propertyKeyword);
+  }
+  void test_parseCompilationUnitMember_function_external_type() {
+    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "external int f()");
+    JUnitTestCase.assertNotNull(declaration.externalKeyword);
+    JUnitTestCase.assertNotNull(declaration.functionExpression);
+    JUnitTestCase.assertNull(declaration.propertyKeyword);
+  }
+  void test_parseCompilationUnitMember_function_noType() {
+    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "f() {}");
+    JUnitTestCase.assertNotNull(declaration.functionExpression);
+    JUnitTestCase.assertNull(declaration.propertyKeyword);
+  }
+  void test_parseCompilationUnitMember_function_type() {
+    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "int f() {}");
+    JUnitTestCase.assertNotNull(declaration.functionExpression);
+    JUnitTestCase.assertNull(declaration.propertyKeyword);
+  }
+  void test_parseCompilationUnitMember_getter_external_noType() {
+    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "external get p");
+    JUnitTestCase.assertNotNull(declaration.externalKeyword);
+    JUnitTestCase.assertNotNull(declaration.functionExpression);
+    JUnitTestCase.assertNotNull(declaration.propertyKeyword);
+  }
+  void test_parseCompilationUnitMember_getter_external_type() {
+    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "external int get p");
+    JUnitTestCase.assertNotNull(declaration.externalKeyword);
+    JUnitTestCase.assertNotNull(declaration.functionExpression);
+    JUnitTestCase.assertNotNull(declaration.propertyKeyword);
+  }
+  void test_parseCompilationUnitMember_getter_noType() {
+    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "get p => 0;");
+    JUnitTestCase.assertNotNull(declaration.functionExpression);
+    JUnitTestCase.assertNotNull(declaration.propertyKeyword);
+  }
+  void test_parseCompilationUnitMember_getter_type() {
+    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "int get p => 0;");
+    JUnitTestCase.assertNotNull(declaration.functionExpression);
+    JUnitTestCase.assertNotNull(declaration.propertyKeyword);
+  }
+  void test_parseCompilationUnitMember_setter_external_noType() {
+    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "external set p(v)");
+    JUnitTestCase.assertNotNull(declaration.externalKeyword);
+    JUnitTestCase.assertNotNull(declaration.functionExpression);
+    JUnitTestCase.assertNotNull(declaration.propertyKeyword);
+  }
+  void test_parseCompilationUnitMember_setter_external_type() {
+    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "external void set p(int v)");
+    JUnitTestCase.assertNotNull(declaration.externalKeyword);
+    JUnitTestCase.assertNotNull(declaration.functionExpression);
+    JUnitTestCase.assertNotNull(declaration.propertyKeyword);
+  }
+  void test_parseCompilationUnitMember_setter_noType() {
+    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "set p(v) {}");
+    JUnitTestCase.assertNotNull(declaration.functionExpression);
+    JUnitTestCase.assertNotNull(declaration.propertyKeyword);
+  }
+  void test_parseCompilationUnitMember_setter_type() {
+    FunctionDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "void set p(int v) {}");
+    JUnitTestCase.assertNotNull(declaration.functionExpression);
+    JUnitTestCase.assertNotNull(declaration.propertyKeyword);
+  }
+  void test_parseCompilationUnitMember_typedef_class_abstract() {
+    ClassTypeAlias typeAlias = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "typedef C = abstract S with M;");
+    JUnitTestCase.assertNotNull(typeAlias.keyword);
+    JUnitTestCase.assertEquals("C", typeAlias.name.name);
+    JUnitTestCase.assertNull(typeAlias.typeParameters);
+    JUnitTestCase.assertNotNull(typeAlias.equals);
+    JUnitTestCase.assertNotNull(typeAlias.abstractKeyword);
+    JUnitTestCase.assertEquals("S", typeAlias.superclass.name.name);
+    JUnitTestCase.assertNotNull(typeAlias.withClause);
+    JUnitTestCase.assertNull(typeAlias.implementsClause);
+    JUnitTestCase.assertNotNull(typeAlias.semicolon);
+  }
+  void test_parseCompilationUnitMember_typedef_class_generic() {
+    ClassTypeAlias typeAlias = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "typedef C<E> = S<E> with M<E> implements I<E>;");
+    JUnitTestCase.assertNotNull(typeAlias.keyword);
+    JUnitTestCase.assertEquals("C", typeAlias.name.name);
+    EngineTestCase.assertSize(1, typeAlias.typeParameters.typeParameters);
+    JUnitTestCase.assertNotNull(typeAlias.equals);
+    JUnitTestCase.assertNull(typeAlias.abstractKeyword);
+    JUnitTestCase.assertEquals("S", typeAlias.superclass.name.name);
+    JUnitTestCase.assertNotNull(typeAlias.withClause);
+    JUnitTestCase.assertNotNull(typeAlias.implementsClause);
+    JUnitTestCase.assertNotNull(typeAlias.semicolon);
+  }
+  void test_parseCompilationUnitMember_typedef_class_implements() {
+    ClassTypeAlias typeAlias = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "typedef C = S with M implements I;");
+    JUnitTestCase.assertNotNull(typeAlias.keyword);
+    JUnitTestCase.assertEquals("C", typeAlias.name.name);
+    JUnitTestCase.assertNull(typeAlias.typeParameters);
+    JUnitTestCase.assertNotNull(typeAlias.equals);
+    JUnitTestCase.assertNull(typeAlias.abstractKeyword);
+    JUnitTestCase.assertEquals("S", typeAlias.superclass.name.name);
+    JUnitTestCase.assertNotNull(typeAlias.withClause);
+    JUnitTestCase.assertNotNull(typeAlias.implementsClause);
+    JUnitTestCase.assertNotNull(typeAlias.semicolon);
+  }
+  void test_parseCompilationUnitMember_typedef_class_noImplements() {
+    ClassTypeAlias typeAlias = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "typedef C = S with M;");
+    JUnitTestCase.assertNotNull(typeAlias.keyword);
+    JUnitTestCase.assertEquals("C", typeAlias.name.name);
+    JUnitTestCase.assertNull(typeAlias.typeParameters);
+    JUnitTestCase.assertNotNull(typeAlias.equals);
+    JUnitTestCase.assertNull(typeAlias.abstractKeyword);
+    JUnitTestCase.assertEquals("S", typeAlias.superclass.name.name);
+    JUnitTestCase.assertNotNull(typeAlias.withClause);
+    JUnitTestCase.assertNull(typeAlias.implementsClause);
+    JUnitTestCase.assertNotNull(typeAlias.semicolon);
+  }
+  void test_parseCompilationUnitMember_typedef_function() {
+    FunctionTypeAlias typeAlias = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "typedef F();");
+    JUnitTestCase.assertEquals("F", typeAlias.name.name);
+    EngineTestCase.assertSize(0, typeAlias.parameters.parameters);
+  }
+  void test_parseCompilationUnitMember_variable() {
+    TopLevelVariableDeclaration declaration = ParserTestCase.parse("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "var x = 0;");
+    JUnitTestCase.assertNotNull(declaration.semicolon);
+    JUnitTestCase.assertNotNull(declaration.variables);
+  }
+  void test_parseConditionalExpression() {
+    ConditionalExpression expression = ParserTestCase.parse4("parseConditionalExpression", "x ? y : z", []);
+    JUnitTestCase.assertNotNull(expression.condition);
+    JUnitTestCase.assertNotNull(expression.question);
+    JUnitTestCase.assertNotNull(expression.thenExpression);
+    JUnitTestCase.assertNotNull(expression.colon);
+    JUnitTestCase.assertNotNull(expression.elseExpression);
+  }
+  void test_parseConstExpression_instanceCreation() {
+    InstanceCreationExpression expression = ParserTestCase.parse4("parseConstExpression", "const A()", []);
+    JUnitTestCase.assertNotNull(expression.keyword);
+    ConstructorName name = expression.constructorName;
+    JUnitTestCase.assertNotNull(name);
+    JUnitTestCase.assertNotNull(name.type);
+    JUnitTestCase.assertNull(name.period);
+    JUnitTestCase.assertNull(name.name);
+    JUnitTestCase.assertNotNull(expression.argumentList);
+  }
+  void test_parseConstExpression_listLiteral_typed() {
+    ListLiteral literal = ParserTestCase.parse4("parseConstExpression", "const <A> []", []);
+    JUnitTestCase.assertNotNull(literal.modifier);
+    JUnitTestCase.assertNotNull(literal.typeArguments);
+    JUnitTestCase.assertNotNull(literal.leftBracket);
+    EngineTestCase.assertSize(0, literal.elements);
+    JUnitTestCase.assertNotNull(literal.rightBracket);
+  }
+  void test_parseConstExpression_listLiteral_untyped() {
+    ListLiteral literal = ParserTestCase.parse4("parseConstExpression", "const []", []);
+    JUnitTestCase.assertNotNull(literal.modifier);
+    JUnitTestCase.assertNull(literal.typeArguments);
+    JUnitTestCase.assertNotNull(literal.leftBracket);
+    EngineTestCase.assertSize(0, literal.elements);
+    JUnitTestCase.assertNotNull(literal.rightBracket);
+  }
+  void test_parseConstExpression_mapLiteral_typed() {
+    MapLiteral literal = ParserTestCase.parse4("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 {}", []);
+    JUnitTestCase.assertNotNull(literal.leftBracket);
+    EngineTestCase.assertSize(0, literal.entries);
+    JUnitTestCase.assertNotNull(literal.rightBracket);
+    JUnitTestCase.assertNull(literal.typeArguments);
+  }
+  void test_parseConstructor() {
+  }
+  void test_parseConstructorFieldInitializer_qualified() {
+    ConstructorFieldInitializer invocation = ParserTestCase.parse4("parseConstructorFieldInitializer", "this.a = b", []);
+    JUnitTestCase.assertNotNull(invocation.equals);
+    JUnitTestCase.assertNotNull(invocation.expression);
+    JUnitTestCase.assertNotNull(invocation.fieldName);
+    JUnitTestCase.assertNotNull(invocation.keyword);
+    JUnitTestCase.assertNotNull(invocation.period);
+  }
+  void test_parseConstructorFieldInitializer_unqualified() {
+    ConstructorFieldInitializer invocation = ParserTestCase.parse4("parseConstructorFieldInitializer", "a = b", []);
+    JUnitTestCase.assertNotNull(invocation.equals);
+    JUnitTestCase.assertNotNull(invocation.expression);
+    JUnitTestCase.assertNotNull(invocation.fieldName);
+    JUnitTestCase.assertNull(invocation.keyword);
+    JUnitTestCase.assertNull(invocation.period);
+  }
+  void test_parseConstructorName_named_noPrefix() {
+    ConstructorName name = ParserTestCase.parse4("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;", []);
+    JUnitTestCase.assertNotNull(name.type);
+    JUnitTestCase.assertNotNull(name.period);
+    JUnitTestCase.assertNotNull(name.name);
+  }
+  void test_parseConstructorName_unnamed_noPrefix() {
+    ConstructorName name = ParserTestCase.parse4("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;", []);
+    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]);
+    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]);
+    JUnitTestCase.assertNotNull(statement.keyword);
+    JUnitTestCase.assertNull(statement.label);
+    JUnitTestCase.assertNotNull(statement.semicolon);
+  }
+  void test_parseDirective_export() {
+    ExportDirective directive = ParserTestCase.parse("parseDirective", <Object> [emptyCommentAndMetadata()], "export 'lib/lib.dart';");
+    JUnitTestCase.assertNotNull(directive.keyword);
+    JUnitTestCase.assertNotNull(directive.libraryUri);
+    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.assertNull(directive.asToken);
+    JUnitTestCase.assertNull(directive.prefix);
+    EngineTestCase.assertSize(0, directive.combinators);
+    JUnitTestCase.assertNotNull(directive.semicolon);
+  }
+  void test_parseDirective_library() {
+    LibraryDirective directive = ParserTestCase.parse("parseDirective", <Object> [emptyCommentAndMetadata()], "library l;");
+    JUnitTestCase.assertNotNull(directive.libraryToken);
+    JUnitTestCase.assertNotNull(directive.name);
+    JUnitTestCase.assertNotNull(directive.semicolon);
+  }
+  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.semicolon);
+  }
+  void test_parseDirective_partOf() {
+    PartOfDirective directive = ParserTestCase.parse("parseDirective", <Object> [emptyCommentAndMetadata()], "part of l;");
+    JUnitTestCase.assertNotNull(directive.partToken);
+    JUnitTestCase.assertNotNull(directive.ofToken);
+    JUnitTestCase.assertNotNull(directive.libraryName);
+    JUnitTestCase.assertNotNull(directive.semicolon);
+  }
+  void test_parseDocumentationComment_block() {
+    Comment comment = ParserTestCase.parse4("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", []);
+    JUnitTestCase.assertFalse(comment.isBlock());
+    JUnitTestCase.assertTrue(comment.isDocumentation());
+    JUnitTestCase.assertFalse(comment.isEndOfLine());
+    NodeList<CommentReference> references2 = comment.references;
+    EngineTestCase.assertSize(1, references2);
+    CommentReference reference = references2[0];
+    JUnitTestCase.assertNotNull(reference);
+    JUnitTestCase.assertEquals(5, reference.offset);
+  }
+  void test_parseDocumentationComment_endOfLine() {
+    Comment comment = ParserTestCase.parse4("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);", []);
+    JUnitTestCase.assertNotNull(statement.doKeyword);
+    JUnitTestCase.assertNotNull(statement.body);
+    JUnitTestCase.assertNotNull(statement.whileKeyword);
+    JUnitTestCase.assertNotNull(statement.leftParenthesis);
+    JUnitTestCase.assertNotNull(statement.condition);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.semicolon);
+  }
+  void test_parseEmptyStatement() {
+    EmptyStatement statement = ParserTestCase.parse4("parseEmptyStatement", ";", []);
+    JUnitTestCase.assertNotNull(statement.semicolon);
+  }
+  void test_parseEqualityExpression_normal() {
+    BinaryExpression expression = ParserTestCase.parse4("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", []);
+    EngineTestCase.assertInstanceOf(SuperExpression, expression.leftOperand);
+    JUnitTestCase.assertNotNull(expression.operator);
+    JUnitTestCase.assertEquals(TokenType.EQ_EQ, expression.operator.type);
+    JUnitTestCase.assertNotNull(expression.rightOperand);
+  }
+  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);
+    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);
+    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);
+    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);
+    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);
+    EngineTestCase.assertSize(2, directive.combinators);
+    JUnitTestCase.assertNotNull(directive.semicolon);
+  }
+  void test_parseExpression_assign() {
+    AssignmentExpression expression = ParserTestCase.parse4("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", []);
+    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)", []);
+    EngineTestCase.assertInstanceOf(FunctionExpression, invocation.function);
+    FunctionExpression expression = invocation.function as FunctionExpression;
+    JUnitTestCase.assertNotNull(expression.parameters);
+    JUnitTestCase.assertNotNull(expression.body);
+    ArgumentList list = invocation.argumentList;
+    JUnitTestCase.assertNotNull(list);
+    EngineTestCase.assertSize(1, list.arguments);
+  }
+  void test_parseExpression_superMethodInvocation() {
+    MethodInvocation invocation = ParserTestCase.parse4("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", []);
+    EngineTestCase.assertSize(3, result);
+  }
+  void test_parseExpressionList_single() {
+    List<Expression> result = ParserTestCase.parse4("parseExpressionList", "1", []);
+    EngineTestCase.assertSize(1, result);
+  }
+  void test_parseExpressionWithoutCascade_assign() {
+    AssignmentExpression expression = ParserTestCase.parse4("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", []);
+    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()", []);
+    JUnitTestCase.assertNotNull(invocation.target);
+    JUnitTestCase.assertNotNull(invocation.methodName);
+    JUnitTestCase.assertNotNull(invocation.argumentList);
+  }
+  void test_parseExtendsClause() {
+    ExtendsClause clause = ParserTestCase.parse4("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);
+    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);
+    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);
+    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);
+    JUnitTestCase.assertNotNull(result.type);
+  }
+  void test_parseFinalConstVarOrType_type_parameterized() {
+    FinalConstVarOrType result = ParserTestCase.parse("parseFinalConstVarOrType", <Object> [false], "A<B> a");
+    JUnitTestCase.assertNull(result.keyword);
+    JUnitTestCase.assertNotNull(result.type);
+  }
+  void test_parseFinalConstVarOrType_type_prefixed() {
+    FinalConstVarOrType result = ParserTestCase.parse("parseFinalConstVarOrType", <Object> [false], "p.A a");
+    JUnitTestCase.assertNull(result.keyword);
+    JUnitTestCase.assertNotNull(result.type);
+  }
+  void test_parseFinalConstVarOrType_type_prefixedAndParameterized() {
+    FinalConstVarOrType result = ParserTestCase.parse("parseFinalConstVarOrType", <Object> [false], "p.A<B> a");
+    JUnitTestCase.assertNull(result.keyword);
+    JUnitTestCase.assertNotNull(result.type);
+  }
+  void test_parseFinalConstVarOrType_type_simple() {
+    FinalConstVarOrType result = ParserTestCase.parse("parseFinalConstVarOrType", <Object> [false], "A a");
+    JUnitTestCase.assertNull(result.keyword);
+    JUnitTestCase.assertNotNull(result.type);
+  }
+  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);
+    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;
+    JUnitTestCase.assertNotNull(simpleParameter.identifier);
+    JUnitTestCase.assertNotNull(simpleParameter.keyword);
+    JUnitTestCase.assertNotNull(simpleParameter.type);
+    JUnitTestCase.assertEquals(kind, simpleParameter.kind);
+    JUnitTestCase.assertNotNull(parameter.separator);
+    JUnitTestCase.assertNotNull(parameter.defaultValue);
+    JUnitTestCase.assertEquals(kind, parameter.kind);
+  }
+  void test_parseFormalParameter_final_withType_normal() {
+    ParameterKind kind = ParameterKind.REQUIRED;
+    SimpleFormalParameter parameter = ParserTestCase.parse("parseFormalParameter", <Object> [kind], "final A a");
+    JUnitTestCase.assertNotNull(parameter.identifier);
+    JUnitTestCase.assertNotNull(parameter.keyword);
+    JUnitTestCase.assertNotNull(parameter.type);
+    JUnitTestCase.assertEquals(kind, parameter.kind);
+  }
+  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;
+    JUnitTestCase.assertNotNull(simpleParameter.identifier);
+    JUnitTestCase.assertNotNull(simpleParameter.keyword);
+    JUnitTestCase.assertNotNull(simpleParameter.type);
+    JUnitTestCase.assertEquals(kind, simpleParameter.kind);
+    JUnitTestCase.assertNotNull(parameter.separator);
+    JUnitTestCase.assertNotNull(parameter.defaultValue);
+    JUnitTestCase.assertEquals(kind, parameter.kind);
+  }
+  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;
+    JUnitTestCase.assertNotNull(simpleParameter.identifier);
+    JUnitTestCase.assertNull(simpleParameter.keyword);
+    JUnitTestCase.assertNotNull(simpleParameter.type);
+    JUnitTestCase.assertEquals(kind, simpleParameter.kind);
+    JUnitTestCase.assertNotNull(parameter.separator);
+    JUnitTestCase.assertNotNull(parameter.defaultValue);
+    JUnitTestCase.assertEquals(kind, parameter.kind);
+  }
+  void test_parseFormalParameter_nonFinal_withType_normal() {
+    ParameterKind kind = ParameterKind.REQUIRED;
+    SimpleFormalParameter parameter = ParserTestCase.parse("parseFormalParameter", <Object> [kind], "A a");
+    JUnitTestCase.assertNotNull(parameter.identifier);
+    JUnitTestCase.assertNull(parameter.keyword);
+    JUnitTestCase.assertNotNull(parameter.type);
+    JUnitTestCase.assertEquals(kind, parameter.kind);
+  }
+  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;
+    JUnitTestCase.assertNotNull(simpleParameter.identifier);
+    JUnitTestCase.assertNull(simpleParameter.keyword);
+    JUnitTestCase.assertNotNull(simpleParameter.type);
+    JUnitTestCase.assertEquals(kind, simpleParameter.kind);
+    JUnitTestCase.assertNotNull(parameter.separator);
+    JUnitTestCase.assertNotNull(parameter.defaultValue);
+    JUnitTestCase.assertEquals(kind, parameter.kind);
+  }
+  void test_parseFormalParameter_var() {
+    ParameterKind kind = ParameterKind.REQUIRED;
+    SimpleFormalParameter parameter = ParserTestCase.parse("parseFormalParameter", <Object> [kind], "var a");
+    JUnitTestCase.assertNotNull(parameter.identifier);
+    JUnitTestCase.assertNotNull(parameter.keyword);
+    JUnitTestCase.assertNull(parameter.type);
+    JUnitTestCase.assertEquals(kind, parameter.kind);
+  }
+  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;
+    JUnitTestCase.assertNotNull(simpleParameter.identifier);
+    JUnitTestCase.assertNotNull(simpleParameter.keyword);
+    JUnitTestCase.assertNull(simpleParameter.type);
+    JUnitTestCase.assertEquals(kind, simpleParameter.kind);
+    JUnitTestCase.assertNotNull(parameter.separator);
+    JUnitTestCase.assertNotNull(parameter.defaultValue);
+    JUnitTestCase.assertEquals(kind, parameter.kind);
+  }
+  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;
+    JUnitTestCase.assertNotNull(simpleParameter.identifier);
+    JUnitTestCase.assertNotNull(simpleParameter.keyword);
+    JUnitTestCase.assertNull(simpleParameter.type);
+    JUnitTestCase.assertEquals(kind, simpleParameter.kind);
+    JUnitTestCase.assertNotNull(parameter.separator);
+    JUnitTestCase.assertNotNull(parameter.defaultValue);
+    JUnitTestCase.assertEquals(kind, parameter.kind);
+  }
+  void test_parseFormalParameterList_empty() {
+    FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "()", []);
+    JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
+    JUnitTestCase.assertNull(parameterList.leftDelimiter);
+    EngineTestCase.assertSize(0, parameterList.parameters);
+    JUnitTestCase.assertNull(parameterList.rightDelimiter);
+    JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
+  }
+  void test_parseFormalParameterList_named_multiple() {
+    FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "({A a : 1, B b, C c : 3})", []);
+    JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
+    JUnitTestCase.assertNotNull(parameterList.leftDelimiter);
+    EngineTestCase.assertSize(3, parameterList.parameters);
+    JUnitTestCase.assertNotNull(parameterList.rightDelimiter);
+    JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
+  }
+  void test_parseFormalParameterList_named_single() {
+    FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "({A a})", []);
+    JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
+    JUnitTestCase.assertNotNull(parameterList.leftDelimiter);
+    EngineTestCase.assertSize(1, parameterList.parameters);
+    JUnitTestCase.assertNotNull(parameterList.rightDelimiter);
+    JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
+  }
+  void test_parseFormalParameterList_normal_multiple() {
+    FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "(A a, B b, C c)", []);
+    JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
+    JUnitTestCase.assertNull(parameterList.leftDelimiter);
+    EngineTestCase.assertSize(3, parameterList.parameters);
+    JUnitTestCase.assertNull(parameterList.rightDelimiter);
+    JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
+  }
+  void test_parseFormalParameterList_normal_named() {
+    FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "(A a, {B b})", []);
+    JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
+    JUnitTestCase.assertNotNull(parameterList.leftDelimiter);
+    EngineTestCase.assertSize(2, parameterList.parameters);
+    JUnitTestCase.assertNotNull(parameterList.rightDelimiter);
+    JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
+  }
+  void test_parseFormalParameterList_normal_positional() {
+    FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "(A a, [B b])", []);
+    JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
+    JUnitTestCase.assertNotNull(parameterList.leftDelimiter);
+    EngineTestCase.assertSize(2, parameterList.parameters);
+    JUnitTestCase.assertNotNull(parameterList.rightDelimiter);
+    JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
+  }
+  void test_parseFormalParameterList_normal_single() {
+    FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "(A a)", []);
+    JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
+    JUnitTestCase.assertNull(parameterList.leftDelimiter);
+    EngineTestCase.assertSize(1, parameterList.parameters);
+    JUnitTestCase.assertNull(parameterList.rightDelimiter);
+    JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
+  }
+  void test_parseFormalParameterList_positional_multiple() {
+    FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "([A a = null, B b, C c = null])", []);
+    JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
+    JUnitTestCase.assertNotNull(parameterList.leftDelimiter);
+    EngineTestCase.assertSize(3, parameterList.parameters);
+    JUnitTestCase.assertNotNull(parameterList.rightDelimiter);
+    JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
+  }
+  void test_parseFormalParameterList_positional_single() {
+    FormalParameterList parameterList = ParserTestCase.parse4("parseFormalParameterList", "([A a = null])", []);
+    JUnitTestCase.assertNotNull(parameterList.leftParenthesis);
+    JUnitTestCase.assertNotNull(parameterList.leftDelimiter);
+    EngineTestCase.assertSize(1, parameterList.parameters);
+    JUnitTestCase.assertNotNull(parameterList.rightDelimiter);
+    JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
+  }
+  void test_parseForStatement_each_identifier() {
+    ForEachStatement statement = ParserTestCase.parse4("parseForStatement", "for (element in list) {}", []);
+    JUnitTestCase.assertNotNull(statement.forKeyword);
+    JUnitTestCase.assertNotNull(statement.leftParenthesis);
+    JUnitTestCase.assertNotNull(statement.loopParameter);
+    JUnitTestCase.assertNotNull(statement.inKeyword);
+    JUnitTestCase.assertNotNull(statement.iterator);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.body);
+  }
+  void test_parseForStatement_each_noType() {
+    ForEachStatement statement = ParserTestCase.parse4("parseForStatement", "for (element in list) {}", []);
+    JUnitTestCase.assertNotNull(statement.forKeyword);
+    JUnitTestCase.assertNotNull(statement.leftParenthesis);
+    JUnitTestCase.assertNotNull(statement.loopParameter);
+    JUnitTestCase.assertNotNull(statement.inKeyword);
+    JUnitTestCase.assertNotNull(statement.iterator);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.body);
+  }
+  void test_parseForStatement_each_type() {
+    ForEachStatement statement = ParserTestCase.parse4("parseForStatement", "for (A element in list) {}", []);
+    JUnitTestCase.assertNotNull(statement.forKeyword);
+    JUnitTestCase.assertNotNull(statement.leftParenthesis);
+    JUnitTestCase.assertNotNull(statement.loopParameter);
+    JUnitTestCase.assertNotNull(statement.inKeyword);
+    JUnitTestCase.assertNotNull(statement.iterator);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.body);
+  }
+  void test_parseForStatement_each_var() {
+    ForEachStatement statement = ParserTestCase.parse4("parseForStatement", "for (var element in list) {}", []);
+    JUnitTestCase.assertNotNull(statement.forKeyword);
+    JUnitTestCase.assertNotNull(statement.leftParenthesis);
+    JUnitTestCase.assertNotNull(statement.loopParameter);
+    JUnitTestCase.assertNotNull(statement.inKeyword);
+    JUnitTestCase.assertNotNull(statement.iterator);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.body);
+  }
+  void test_parseForStatement_loop_c() {
+    ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (; i < count;) {}", []);
+    JUnitTestCase.assertNotNull(statement.forKeyword);
+    JUnitTestCase.assertNotNull(statement.leftParenthesis);
+    JUnitTestCase.assertNull(statement.variables);
+    JUnitTestCase.assertNull(statement.initialization);
+    JUnitTestCase.assertNotNull(statement.leftSeparator);
+    JUnitTestCase.assertNotNull(statement.condition);
+    JUnitTestCase.assertNotNull(statement.rightSeparator);
+    EngineTestCase.assertSize(0, statement.updaters);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.body);
+  }
+  void test_parseForStatement_loop_cu() {
+    ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (; i < count; i++) {}", []);
+    JUnitTestCase.assertNotNull(statement.forKeyword);
+    JUnitTestCase.assertNotNull(statement.leftParenthesis);
+    JUnitTestCase.assertNull(statement.variables);
+    JUnitTestCase.assertNull(statement.initialization);
+    JUnitTestCase.assertNotNull(statement.leftSeparator);
+    JUnitTestCase.assertNotNull(statement.condition);
+    JUnitTestCase.assertNotNull(statement.rightSeparator);
+    EngineTestCase.assertSize(1, statement.updaters);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.body);
+  }
+  void test_parseForStatement_loop_ecu() {
+    ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (i--; i < count; i++) {}", []);
+    JUnitTestCase.assertNotNull(statement.forKeyword);
+    JUnitTestCase.assertNotNull(statement.leftParenthesis);
+    JUnitTestCase.assertNull(statement.variables);
+    JUnitTestCase.assertNotNull(statement.initialization);
+    JUnitTestCase.assertNotNull(statement.leftSeparator);
+    JUnitTestCase.assertNotNull(statement.condition);
+    JUnitTestCase.assertNotNull(statement.rightSeparator);
+    EngineTestCase.assertSize(1, statement.updaters);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.body);
+  }
+  void test_parseForStatement_loop_i() {
+    ForStatement statement = ParserTestCase.parse4("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);
+    JUnitTestCase.assertNull(statement.initialization);
+    JUnitTestCase.assertNotNull(statement.leftSeparator);
+    JUnitTestCase.assertNull(statement.condition);
+    JUnitTestCase.assertNotNull(statement.rightSeparator);
+    EngineTestCase.assertSize(0, statement.updaters);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.body);
+  }
+  void test_parseForStatement_loop_ic() {
+    ForStatement statement = ParserTestCase.parse4("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);
+    JUnitTestCase.assertNull(statement.initialization);
+    JUnitTestCase.assertNotNull(statement.leftSeparator);
+    JUnitTestCase.assertNotNull(statement.condition);
+    JUnitTestCase.assertNotNull(statement.rightSeparator);
+    EngineTestCase.assertSize(0, statement.updaters);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.body);
+  }
+  void test_parseForStatement_loop_icu() {
+    ForStatement statement = ParserTestCase.parse4("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);
+    JUnitTestCase.assertNull(statement.initialization);
+    JUnitTestCase.assertNotNull(statement.leftSeparator);
+    JUnitTestCase.assertNotNull(statement.condition);
+    JUnitTestCase.assertNotNull(statement.rightSeparator);
+    EngineTestCase.assertSize(1, statement.updaters);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.body);
+  }
+  void test_parseForStatement_loop_iicuu() {
+    ForStatement statement = ParserTestCase.parse4("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);
+    JUnitTestCase.assertNull(statement.initialization);
+    JUnitTestCase.assertNotNull(statement.leftSeparator);
+    JUnitTestCase.assertNotNull(statement.condition);
+    JUnitTestCase.assertNotNull(statement.rightSeparator);
+    EngineTestCase.assertSize(2, statement.updaters);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.body);
+  }
+  void test_parseForStatement_loop_iu() {
+    ForStatement statement = ParserTestCase.parse4("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);
+    JUnitTestCase.assertNull(statement.initialization);
+    JUnitTestCase.assertNotNull(statement.leftSeparator);
+    JUnitTestCase.assertNull(statement.condition);
+    JUnitTestCase.assertNotNull(statement.rightSeparator);
+    EngineTestCase.assertSize(1, statement.updaters);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.body);
+  }
+  void test_parseForStatement_loop_u() {
+    ForStatement statement = ParserTestCase.parse4("parseForStatement", "for (;; i++) {}", []);
+    JUnitTestCase.assertNotNull(statement.forKeyword);
+    JUnitTestCase.assertNotNull(statement.leftParenthesis);
+    JUnitTestCase.assertNull(statement.variables);
+    JUnitTestCase.assertNull(statement.initialization);
+    JUnitTestCase.assertNotNull(statement.leftSeparator);
+    JUnitTestCase.assertNull(statement.condition);
+    JUnitTestCase.assertNotNull(statement.rightSeparator);
+    EngineTestCase.assertSize(1, statement.updaters);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.body);
+  }
+  void test_parseFunctionBody_block() {
+    BlockFunctionBody functionBody = ParserTestCase.parse("parseFunctionBody", <Object> [false, false], "{}");
+    JUnitTestCase.assertNotNull(functionBody.block);
+  }
+  void test_parseFunctionBody_empty() {
+    EmptyFunctionBody functionBody = ParserTestCase.parse("parseFunctionBody", <Object> [true, false], ";");
+    JUnitTestCase.assertNotNull(functionBody.semicolon);
+  }
+  void test_parseFunctionBody_expression() {
+    ExpressionFunctionBody functionBody = ParserTestCase.parse("parseFunctionBody", <Object> [false, false], "=> y;");
+    JUnitTestCase.assertNotNull(functionBody.functionDefinition);
+    JUnitTestCase.assertNotNull(functionBody.expression);
+    JUnitTestCase.assertNotNull(functionBody.semicolon);
+  }
+  void test_parseFunctionDeclaration_function() {
+    Comment comment = Comment.createDocumentationComment(new List<Token>.fixedLength(0));
+    TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
+    FunctionDeclaration declaration = ParserTestCase.parse("parseFunctionDeclaration", <Object> [commentAndMetadata(comment, []), null, returnType, false], "f() {}");
+    JUnitTestCase.assertEquals(comment, declaration.documentationComment);
+    JUnitTestCase.assertEquals(returnType, declaration.returnType);
+    JUnitTestCase.assertNotNull(declaration.name);
+    FunctionExpression expression = declaration.functionExpression;
+    JUnitTestCase.assertNotNull(expression);
+    JUnitTestCase.assertNotNull(expression.body);
+    JUnitTestCase.assertNotNull(expression.parameters);
+    JUnitTestCase.assertNull(declaration.propertyKeyword);
+  }
+  void test_parseFunctionDeclaration_function_inStatement() {
+    Comment comment = Comment.createDocumentationComment(new List<Token>.fixedLength(0));
+    TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
+    FunctionDeclaration declaration = ParserTestCase.parse("parseFunctionDeclaration", <Object> [commentAndMetadata(comment, []), null, returnType, true], "f() {};");
+    JUnitTestCase.assertEquals(comment, declaration.documentationComment);
+    JUnitTestCase.assertEquals(returnType, declaration.returnType);
+    JUnitTestCase.assertNotNull(declaration.name);
+    FunctionExpression expression = declaration.functionExpression;
+    JUnitTestCase.assertNotNull(expression);
+    JUnitTestCase.assertNotNull(expression.body);
+    JUnitTestCase.assertNotNull(expression.parameters);
+    JUnitTestCase.assertNull(declaration.propertyKeyword);
+  }
+  void test_parseFunctionDeclaration_getter() {
+    Comment comment = Comment.createDocumentationComment(new List<Token>.fixedLength(0));
+    TypeName returnType = new TypeName(new SimpleIdentifier(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);
+    JUnitTestCase.assertNotNull(declaration.name);
+    FunctionExpression expression = declaration.functionExpression;
+    JUnitTestCase.assertNotNull(expression);
+    JUnitTestCase.assertNotNull(expression.body);
+    JUnitTestCase.assertNull(expression.parameters);
+    JUnitTestCase.assertNotNull(declaration.propertyKeyword);
+  }
+  void test_parseFunctionDeclaration_setter() {
+    Comment comment = Comment.createDocumentationComment(new List<Token>.fixedLength(0));
+    TypeName returnType = new TypeName(new SimpleIdentifier(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);
+    JUnitTestCase.assertNotNull(declaration.name);
+    FunctionExpression expression = declaration.functionExpression;
+    JUnitTestCase.assertNotNull(expression);
+    JUnitTestCase.assertNotNull(expression.body);
+    JUnitTestCase.assertNotNull(expression.parameters);
+    JUnitTestCase.assertNotNull(declaration.propertyKeyword);
+  }
+  void test_parseFunctionDeclarationStatement() {
+    FunctionDeclarationStatement statement = ParserTestCase.parse4("parseFunctionDeclarationStatement", "void f(int p) => p * 2;", []);
+    JUnitTestCase.assertNotNull(statement.functionDeclaration);
+  }
+  void test_parseFunctionExpression_body_inExpression() {
+    FunctionExpression expression = ParserTestCase.parse4("parseFunctionExpression", "(int i) => i++", []);
+    JUnitTestCase.assertNotNull(expression.body);
+    JUnitTestCase.assertNotNull(expression.parameters);
+    JUnitTestCase.assertNull((expression.body as ExpressionFunctionBody).semicolon);
+  }
+  void test_parseFunctionExpression_minimal() {
+    FunctionExpression expression = ParserTestCase.parse4("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);
+    MethodDeclaration method = ParserTestCase.parse("parseGetter", <Object> [commentAndMetadata(comment, []), null, null, returnType], "get a;");
+    JUnitTestCase.assertNotNull(method.body);
+    JUnitTestCase.assertEquals(comment, method.documentationComment);
+    JUnitTestCase.assertNull(method.externalKeyword);
+    JUnitTestCase.assertNull(method.modifierKeyword);
+    JUnitTestCase.assertNotNull(method.name);
+    JUnitTestCase.assertNull(method.operatorKeyword);
+    JUnitTestCase.assertNull(method.parameters);
+    JUnitTestCase.assertNotNull(method.propertyKeyword);
+    JUnitTestCase.assertEquals(returnType, method.returnType);
+  }
+  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);
+    MethodDeclaration method = ParserTestCase.parse("parseGetter", <Object> [commentAndMetadata(comment, []), null, staticKeyword, returnType], "get a;");
+    JUnitTestCase.assertNotNull(method.body);
+    JUnitTestCase.assertEquals(comment, method.documentationComment);
+    JUnitTestCase.assertNull(method.externalKeyword);
+    JUnitTestCase.assertEquals(staticKeyword, method.modifierKeyword);
+    JUnitTestCase.assertNotNull(method.name);
+    JUnitTestCase.assertNull(method.operatorKeyword);
+    JUnitTestCase.assertNull(method.parameters);
+    JUnitTestCase.assertNotNull(method.propertyKeyword);
+    JUnitTestCase.assertEquals(returnType, method.returnType);
+  }
+  void test_parseIdentifierList_multiple() {
+    List<SimpleIdentifier> list = ParserTestCase.parse4("parseIdentifierList", "a, b, c", []);
+    EngineTestCase.assertSize(3, list);
+  }
+  void test_parseIdentifierList_single() {
+    List<SimpleIdentifier> list = ParserTestCase.parse4("parseIdentifierList", "a", []);
+    EngineTestCase.assertSize(1, list);
+  }
+  void test_parseIfStatement_else_block() {
+    IfStatement statement = ParserTestCase.parse4("parseIfStatement", "if (x) {} else {}", []);
+    JUnitTestCase.assertNotNull(statement.ifKeyword);
+    JUnitTestCase.assertNotNull(statement.leftParenthesis);
+    JUnitTestCase.assertNotNull(statement.condition);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.thenStatement);
+    JUnitTestCase.assertNotNull(statement.elseKeyword);
+    JUnitTestCase.assertNotNull(statement.elseStatement);
+  }
+  void test_parseIfStatement_else_statement() {
+    IfStatement statement = ParserTestCase.parse4("parseIfStatement", "if (x) f(x); else f(y);", []);
+    JUnitTestCase.assertNotNull(statement.ifKeyword);
+    JUnitTestCase.assertNotNull(statement.leftParenthesis);
+    JUnitTestCase.assertNotNull(statement.condition);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.thenStatement);
+    JUnitTestCase.assertNotNull(statement.elseKeyword);
+    JUnitTestCase.assertNotNull(statement.elseStatement);
+  }
+  void test_parseIfStatement_noElse_block() {
+    IfStatement statement = ParserTestCase.parse4("parseIfStatement", "if (x) {}", []);
+    JUnitTestCase.assertNotNull(statement.ifKeyword);
+    JUnitTestCase.assertNotNull(statement.leftParenthesis);
+    JUnitTestCase.assertNotNull(statement.condition);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.thenStatement);
+    JUnitTestCase.assertNull(statement.elseKeyword);
+    JUnitTestCase.assertNull(statement.elseStatement);
+  }
+  void test_parseIfStatement_noElse_statement() {
+    IfStatement statement = ParserTestCase.parse4("parseIfStatement", "if (x) f(x);", []);
+    JUnitTestCase.assertNotNull(statement.ifKeyword);
+    JUnitTestCase.assertNotNull(statement.leftParenthesis);
+    JUnitTestCase.assertNotNull(statement.condition);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.thenStatement);
+    JUnitTestCase.assertNull(statement.elseKeyword);
+    JUnitTestCase.assertNull(statement.elseStatement);
+  }
+  void test_parseImplementsClause_multiple() {
+    ImplementsClause clause = ParserTestCase.parse4("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", []);
+    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.assertNull(directive.asToken);
+    JUnitTestCase.assertNull(directive.prefix);
+    EngineTestCase.assertSize(1, directive.combinators);
+    JUnitTestCase.assertNotNull(directive.semicolon);
+  }
+  void test_parseImportDirective_noCombinator() {
+    ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart';");
+    JUnitTestCase.assertNotNull(directive.keyword);
+    JUnitTestCase.assertNotNull(directive.libraryUri);
+    JUnitTestCase.assertNull(directive.asToken);
+    JUnitTestCase.assertNull(directive.prefix);
+    EngineTestCase.assertSize(0, directive.combinators);
+    JUnitTestCase.assertNotNull(directive.semicolon);
+  }
+  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.asToken);
+    JUnitTestCase.assertNotNull(directive.prefix);
+    EngineTestCase.assertSize(0, directive.combinators);
+    JUnitTestCase.assertNotNull(directive.semicolon);
+  }
+  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.asToken);
+    JUnitTestCase.assertNotNull(directive.prefix);
+    EngineTestCase.assertSize(2, directive.combinators);
+    JUnitTestCase.assertNotNull(directive.semicolon);
+  }
+  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.asToken);
+    JUnitTestCase.assertNotNull(directive.prefix);
+    EngineTestCase.assertSize(2, directive.combinators);
+    JUnitTestCase.assertNotNull(directive.semicolon);
+  }
+  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.assertNull(directive.asToken);
+    JUnitTestCase.assertNull(directive.prefix);
+    EngineTestCase.assertSize(1, directive.combinators);
+    JUnitTestCase.assertNotNull(directive.semicolon);
+  }
+  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);
+    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);
+    JUnitTestCase.assertEquals(staticKeyword, declaration.keyword);
+    JUnitTestCase.assertNotNull(declaration.semicolon);
+  }
+  void test_parseInitializedIdentifierList_var() {
+    Comment comment = Comment.createDocumentationComment(new List<Token>.fixedLength(0));
+    Token staticKeyword = TokenFactory.token(Keyword.STATIC);
+    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);
+    JUnitTestCase.assertEquals(staticKeyword, declaration.keyword);
+    JUnitTestCase.assertNotNull(declaration.semicolon);
+  }
+  void test_parseInstanceCreationExpression_qualifiedType() {
+    Token token5 = TokenFactory.token(Keyword.NEW);
+    InstanceCreationExpression expression = ParserTestCase.parse("parseInstanceCreationExpression", <Object> [token5], "A.B()");
+    JUnitTestCase.assertEquals(token5, expression.keyword);
+    ConstructorName name = expression.constructorName;
+    JUnitTestCase.assertNotNull(name);
+    JUnitTestCase.assertNotNull(name.type);
+    JUnitTestCase.assertNull(name.period);
+    JUnitTestCase.assertNull(name.name);
+    JUnitTestCase.assertNotNull(expression.argumentList);
+  }
+  void test_parseInstanceCreationExpression_qualifiedType_named() {
+    Token token6 = TokenFactory.token(Keyword.NEW);
+    InstanceCreationExpression expression = ParserTestCase.parse("parseInstanceCreationExpression", <Object> [token6], "A.B.c()");
+    JUnitTestCase.assertEquals(token6, expression.keyword);
+    ConstructorName name = expression.constructorName;
+    JUnitTestCase.assertNotNull(name);
+    JUnitTestCase.assertNotNull(name.type);
+    JUnitTestCase.assertNotNull(name.period);
+    JUnitTestCase.assertNotNull(name.name);
+    JUnitTestCase.assertNotNull(expression.argumentList);
+  }
+  void test_parseInstanceCreationExpression_type() {
+    Token token7 = TokenFactory.token(Keyword.NEW);
+    InstanceCreationExpression expression = ParserTestCase.parse("parseInstanceCreationExpression", <Object> [token7], "A()");
+    JUnitTestCase.assertEquals(token7, expression.keyword);
+    ConstructorName name = expression.constructorName;
+    JUnitTestCase.assertNotNull(name);
+    JUnitTestCase.assertNotNull(name.type);
+    JUnitTestCase.assertNull(name.period);
+    JUnitTestCase.assertNull(name.name);
+    JUnitTestCase.assertNotNull(expression.argumentList);
+  }
+  void test_parseInstanceCreationExpression_type_named() {
+    Token token8 = TokenFactory.token(Keyword.NEW);
+    InstanceCreationExpression expression = ParserTestCase.parse("parseInstanceCreationExpression", <Object> [token8], "A<B>.c()");
+    JUnitTestCase.assertEquals(token8, expression.keyword);
+    ConstructorName name = expression.constructorName;
+    JUnitTestCase.assertNotNull(name);
+    JUnitTestCase.assertNotNull(name.type);
+    JUnitTestCase.assertNotNull(name.period);
+    JUnitTestCase.assertNotNull(name.name);
+    JUnitTestCase.assertNotNull(expression.argumentList);
+  }
+  void test_parseLibraryDirective() {
+    LibraryDirective directive = ParserTestCase.parse("parseLibraryDirective", <Object> [emptyCommentAndMetadata()], "library l;");
+    JUnitTestCase.assertNotNull(directive.libraryToken);
+    JUnitTestCase.assertNotNull(directive.name);
+    JUnitTestCase.assertNotNull(directive.semicolon);
+  }
+  void test_parseLibraryIdentifier_multiple() {
+    String name = "a.b.c";
+    LibraryIdentifier identifier = ParserTestCase.parse4("parseLibraryIdentifier", name, []);
+    JUnitTestCase.assertEquals(name, identifier.name);
+  }
+  void test_parseLibraryIdentifier_single() {
+    String name = "a";
+    LibraryIdentifier identifier = ParserTestCase.parse4("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);
+    ListLiteral literal = ParserTestCase.parse("parseListLiteral", <Object> [token9, typeArguments], "[]");
+    JUnitTestCase.assertEquals(token9, literal.modifier);
+    JUnitTestCase.assertEquals(typeArguments, literal.typeArguments);
+    JUnitTestCase.assertNotNull(literal.leftBracket);
+    EngineTestCase.assertSize(0, literal.elements);
+    JUnitTestCase.assertNotNull(literal.rightBracket);
+  }
+  void test_parseListLiteral_empty_twoTokens() {
+    Token token10 = TokenFactory.token(Keyword.CONST);
+    TypeArgumentList typeArguments = new TypeArgumentList(null, null, null);
+    ListLiteral literal = ParserTestCase.parse("parseListLiteral", <Object> [token10, typeArguments], "[ ]");
+    JUnitTestCase.assertEquals(token10, literal.modifier);
+    JUnitTestCase.assertEquals(typeArguments, literal.typeArguments);
+    JUnitTestCase.assertNotNull(literal.leftBracket);
+    EngineTestCase.assertSize(0, literal.elements);
+    JUnitTestCase.assertNotNull(literal.rightBracket);
+  }
+  void test_parseListLiteral_multiple() {
+    ListLiteral literal = ParserTestCase.parse("parseListLiteral", <Object> [null, null], "[1, 2, 3]");
+    JUnitTestCase.assertNull(literal.modifier);
+    JUnitTestCase.assertNull(literal.typeArguments);
+    JUnitTestCase.assertNotNull(literal.leftBracket);
+    EngineTestCase.assertSize(3, literal.elements);
+    JUnitTestCase.assertNotNull(literal.rightBracket);
+  }
+  void test_parseListLiteral_single() {
+    ListLiteral literal = ParserTestCase.parse("parseListLiteral", <Object> [null, null], "[1]");
+    JUnitTestCase.assertNull(literal.modifier);
+    JUnitTestCase.assertNull(literal.typeArguments);
+    JUnitTestCase.assertNotNull(literal.leftBracket);
+    EngineTestCase.assertSize(1, literal.elements);
+    JUnitTestCase.assertNotNull(literal.rightBracket);
+  }
+  void test_parseListOrMapLiteral_list_noType() {
+    ListLiteral literal = ParserTestCase.parse("parseListOrMapLiteral", <Object> [null], "[1]");
+    JUnitTestCase.assertNull(literal.modifier);
+    JUnitTestCase.assertNull(literal.typeArguments);
+    JUnitTestCase.assertNotNull(literal.leftBracket);
+    EngineTestCase.assertSize(1, literal.elements);
+    JUnitTestCase.assertNotNull(literal.rightBracket);
+  }
+  void test_parseListOrMapLiteral_list_type() {
+    ListLiteral literal = ParserTestCase.parse("parseListOrMapLiteral", <Object> [null], "<int> [1]");
+    JUnitTestCase.assertNull(literal.modifier);
+    JUnitTestCase.assertNotNull(literal.typeArguments);
+    JUnitTestCase.assertNotNull(literal.leftBracket);
+    EngineTestCase.assertSize(1, literal.elements);
+    JUnitTestCase.assertNotNull(literal.rightBracket);
+  }
+  void test_parseListOrMapLiteral_map_noType() {
+    MapLiteral literal = ParserTestCase.parse("parseListOrMapLiteral", <Object> [null], "{'1' : 1}");
+    JUnitTestCase.assertNull(literal.modifier);
+    JUnitTestCase.assertNull(literal.typeArguments);
+    JUnitTestCase.assertNotNull(literal.leftBracket);
+    EngineTestCase.assertSize(1, literal.entries);
+    JUnitTestCase.assertNotNull(literal.rightBracket);
+  }
+  void test_parseListOrMapLiteral_map_type() {
+    MapLiteral literal = ParserTestCase.parse("parseListOrMapLiteral", <Object> [null], "<int> {'1' : 1}");
+    JUnitTestCase.assertNull(literal.modifier);
+    JUnitTestCase.assertNotNull(literal.typeArguments);
+    JUnitTestCase.assertNotNull(literal.leftBracket);
+    EngineTestCase.assertSize(1, literal.entries);
+    JUnitTestCase.assertNotNull(literal.rightBracket);
+  }
+  void test_parseLogicalAndExpression() {
+    BinaryExpression expression = ParserTestCase.parse4("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", []);
+    JUnitTestCase.assertNotNull(expression.leftOperand);
+    JUnitTestCase.assertNotNull(expression.operator);
+    JUnitTestCase.assertEquals(TokenType.BAR_BAR, expression.operator.type);
+    JUnitTestCase.assertNotNull(expression.rightOperand);
+  }
+  void test_parseMapLiteral_empty() {
+    Token token11 = TokenFactory.token(Keyword.CONST);
+    TypeArgumentList typeArguments = new TypeArgumentList(null, null, null);
+    MapLiteral literal = ParserTestCase.parse("parseMapLiteral", <Object> [token11, typeArguments], "{}");
+    JUnitTestCase.assertEquals(token11, literal.modifier);
+    JUnitTestCase.assertEquals(typeArguments, literal.typeArguments);
+    JUnitTestCase.assertNotNull(literal.leftBracket);
+    EngineTestCase.assertSize(0, literal.entries);
+    JUnitTestCase.assertNotNull(literal.rightBracket);
+  }
+  void test_parseMapLiteral_multiple() {
+    MapLiteral literal = ParserTestCase.parse("parseMapLiteral", <Object> [null, null], "{'a' : b, 'x' : y}");
+    JUnitTestCase.assertNotNull(literal.leftBracket);
+    EngineTestCase.assertSize(2, literal.entries);
+    JUnitTestCase.assertNotNull(literal.rightBracket);
+  }
+  void test_parseMapLiteral_single() {
+    MapLiteral literal = ParserTestCase.parse("parseMapLiteral", <Object> [null, null], "{'x' : y}");
+    JUnitTestCase.assertNotNull(literal.leftBracket);
+    EngineTestCase.assertSize(1, literal.entries);
+    JUnitTestCase.assertNotNull(literal.rightBracket);
+  }
+  void test_parseMapLiteralEntry() {
+    MapLiteralEntry entry = ParserTestCase.parse4("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", []);
+    JUnitTestCase.assertNotNull(modifiers.abstractKeyword);
+  }
+  void test_parseModifiers_const() {
+    Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "const A", []);
+    JUnitTestCase.assertNotNull(modifiers.constKeyword);
+  }
+  void test_parseModifiers_external() {
+    Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "external A", []);
+    JUnitTestCase.assertNotNull(modifiers.externalKeyword);
+  }
+  void test_parseModifiers_factory() {
+    Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "factory A", []);
+    JUnitTestCase.assertNotNull(modifiers.factoryKeyword);
+  }
+  void test_parseModifiers_final() {
+    Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "final A", []);
+    JUnitTestCase.assertNotNull(modifiers.finalKeyword);
+  }
+  void test_parseModifiers_static() {
+    Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "static A", []);
+    JUnitTestCase.assertNotNull(modifiers.staticKeyword);
+  }
+  void test_parseModifiers_var() {
+    Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "var A", []);
+    JUnitTestCase.assertNotNull(modifiers.varKeyword);
+  }
+  void test_parseMultiplicativeExpression_normal() {
+    BinaryExpression expression = ParserTestCase.parse4("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", []);
+    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()", []);
+    JUnitTestCase.assertNotNull(expression.keyword);
+    ConstructorName name = expression.constructorName;
+    JUnitTestCase.assertNotNull(name);
+    JUnitTestCase.assertNotNull(name.type);
+    JUnitTestCase.assertNull(name.period);
+    JUnitTestCase.assertNull(name.name);
+    JUnitTestCase.assertNotNull(expression.argumentList);
+  }
+  void test_parseNonLabeledStatement_const_list_empty() {
+    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "const [];", []);
+    JUnitTestCase.assertNotNull(statement.expression);
+  }
+  void test_parseNonLabeledStatement_const_list_nonEmpty() {
+    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "const [1, 2];", []);
+    JUnitTestCase.assertNotNull(statement.expression);
+  }
+  void test_parseNonLabeledStatement_const_map_empty() {
+    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "const {};", []);
+    JUnitTestCase.assertNotNull(statement.expression);
+  }
+  void test_parseNonLabeledStatement_const_map_nonEmpty() {
+    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "const {'a' : 1};", []);
+    JUnitTestCase.assertNotNull(statement.expression);
+  }
+  void test_parseNonLabeledStatement_const_object() {
+    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "const A();", []);
+    JUnitTestCase.assertNotNull(statement.expression);
+  }
+  void test_parseNonLabeledStatement_const_object_named_typeParameters() {
+    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "const A<B>.c();", []);
+    JUnitTestCase.assertNotNull(statement.expression);
+  }
+  void test_parseNonLabeledStatement_constructorInvocation() {
+    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "new C().m();", []);
+    JUnitTestCase.assertNotNull(statement.expression);
+  }
+  void test_parseNonLabeledStatement_false() {
+    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "false;", []);
+    JUnitTestCase.assertNotNull(statement.expression);
+  }
+  void test_parseNonLabeledStatement_functionDeclaration() {
+    ParserTestCase.parse4("parseNonLabeledStatement", "f() {};", []);
+  }
+  void test_parseNonLabeledStatement_functionDeclaration_arguments() {
+    ParserTestCase.parse4("parseNonLabeledStatement", "f(void g()) {};", []);
+  }
+  void test_parseNonLabeledStatement_functionExpressionIndex() {
+    ParserTestCase.parse4("parseNonLabeledStatement", "() {}[0] = null;", []);
+  }
+  void test_parseNonLabeledStatement_functionInvocation() {
+    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "f();", []);
+    JUnitTestCase.assertNotNull(statement.expression);
+  }
+  void test_parseNonLabeledStatement_invokeFunctionExpression() {
+    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "(a) {return a + a;} (3);", []);
+    EngineTestCase.assertInstanceOf(FunctionExpressionInvocation, statement.expression);
+    FunctionExpressionInvocation invocation = statement.expression as FunctionExpressionInvocation;
+    EngineTestCase.assertInstanceOf(FunctionExpression, invocation.function);
+    FunctionExpression expression = invocation.function as FunctionExpression;
+    JUnitTestCase.assertNotNull(expression.parameters);
+    JUnitTestCase.assertNotNull(expression.body);
+    ArgumentList list = invocation.argumentList;
+    JUnitTestCase.assertNotNull(list);
+    EngineTestCase.assertSize(1, list.arguments);
+  }
+  void test_parseNonLabeledStatement_null() {
+    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "null;", []);
+    JUnitTestCase.assertNotNull(statement.expression);
+  }
+  void test_parseNonLabeledStatement_startingWithBuiltInIdentifier() {
+    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "library.getName();", []);
+    JUnitTestCase.assertNotNull(statement.expression);
+  }
+  void test_parseNonLabeledStatement_true() {
+    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "true;", []);
+    JUnitTestCase.assertNotNull(statement.expression);
+  }
+  void test_parseNonLabeledStatement_typeCast() {
+    ExpressionStatement statement = ParserTestCase.parse4("parseNonLabeledStatement", "double.NAN as num;", []);
+    JUnitTestCase.assertNotNull(statement.expression);
+  }
+  void test_parseNormalFormalParameter_field_const_noType() {
+    FieldFormalParameter parameter = ParserTestCase.parse4("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)", []);
+    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)", []);
+    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)", []);
+    JUnitTestCase.assertNotNull(parameter.keyword);
+    JUnitTestCase.assertNotNull(parameter.type);
+    JUnitTestCase.assertNotNull(parameter.identifier);
+  }
+  void test_parseNormalFormalParameter_field_noType() {
+    FieldFormalParameter parameter = ParserTestCase.parse4("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)", []);
+    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)", []);
+    JUnitTestCase.assertNotNull(parameter.keyword);
+    JUnitTestCase.assertNull(parameter.type);
+    JUnitTestCase.assertNotNull(parameter.identifier);
+  }
+  void test_parseNormalFormalParameter_function_noType() {
+    FunctionTypedFormalParameter parameter = ParserTestCase.parse4("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())", []);
+    JUnitTestCase.assertNotNull(parameter.returnType);
+    JUnitTestCase.assertNotNull(parameter.identifier);
+    JUnitTestCase.assertNotNull(parameter.parameters);
+  }
+  void test_parseNormalFormalParameter_function_void() {
+    FunctionTypedFormalParameter parameter = ParserTestCase.parse4("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)", []);
+    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)", []);
+    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)", []);
+    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)", []);
+    JUnitTestCase.assertNotNull(parameter.keyword);
+    JUnitTestCase.assertNotNull(parameter.type);
+    JUnitTestCase.assertNotNull(parameter.identifier);
+  }
+  void test_parseNormalFormalParameter_simple_noType() {
+    SimpleFormalParameter parameter = ParserTestCase.parse4("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)", []);
+    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);
+    MethodDeclaration method = ParserTestCase.parse("parseOperator", <Object> [commentAndMetadata(comment, []), null, returnType], "operator +(A a);");
+    JUnitTestCase.assertNotNull(method.body);
+    JUnitTestCase.assertEquals(comment, method.documentationComment);
+    JUnitTestCase.assertNull(method.externalKeyword);
+    JUnitTestCase.assertNull(method.modifierKeyword);
+    JUnitTestCase.assertNotNull(method.name);
+    JUnitTestCase.assertNotNull(method.operatorKeyword);
+    JUnitTestCase.assertNotNull(method.parameters);
+    JUnitTestCase.assertNull(method.propertyKeyword);
+    JUnitTestCase.assertEquals(returnType, method.returnType);
+  }
+  void test_parseOptionalReturnType() {
+  }
+  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.semicolon);
+  }
+  void test_parsePartDirective_partOf() {
+    PartOfDirective directive = ParserTestCase.parse("parsePartDirective", <Object> [emptyCommentAndMetadata()], "part of l;");
+    JUnitTestCase.assertNotNull(directive.partToken);
+    JUnitTestCase.assertNotNull(directive.ofToken);
+    JUnitTestCase.assertNotNull(directive.libraryName);
+    JUnitTestCase.assertNotNull(directive.semicolon);
+  }
+  void test_parsePostfixExpression_decrement() {
+    PostfixExpression expression = ParserTestCase.parse4("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++", []);
+    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]", []);
+    JUnitTestCase.assertNotNull(expression.array);
+    JUnitTestCase.assertNotNull(expression.index);
+  }
+  void test_parsePostfixExpression_none_methodInvocation() {
+    MethodInvocation expression = ParserTestCase.parse4("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", []);
+    JUnitTestCase.assertNotNull(expression.prefix);
+    JUnitTestCase.assertNotNull(expression.identifier);
+  }
+  void test_parsePrefixedIdentifier_noPrefix() {
+    String lexeme = "bar";
+    SimpleIdentifier identifier = ParserTestCase.parse4("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, []);
+    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", []);
+    JUnitTestCase.assertNotNull(expression.question);
+    JUnitTestCase.assertNotNull(expression.identifier);
+  }
+  void test_parsePrimaryExpression_const() {
+    InstanceCreationExpression expression = ParserTestCase.parse4("parsePrimaryExpression", "const A()", []);
+    JUnitTestCase.assertNotNull(expression);
+  }
+  void test_parsePrimaryExpression_double() {
+    String doubleLiteral = "3.2e4";
+    DoubleLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", doubleLiteral, []);
+    JUnitTestCase.assertNotNull(literal.literal);
+    JUnitTestCase.assertEquals(double.parse(doubleLiteral), literal.value);
+  }
+  void test_parsePrimaryExpression_false() {
+    BooleanLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "false", []);
+    JUnitTestCase.assertNotNull(literal.literal);
+    JUnitTestCase.assertFalse(literal.value);
+  }
+  void test_parsePrimaryExpression_function_arguments() {
+    FunctionExpression expression = ParserTestCase.parse4("parsePrimaryExpression", "(int i) => i + 1", []);
+    JUnitTestCase.assertNotNull(expression.parameters);
+    JUnitTestCase.assertNotNull(expression.body);
+  }
+  void test_parsePrimaryExpression_function_noArguments() {
+    FunctionExpression expression = ParserTestCase.parse4("parsePrimaryExpression", "() => 42", []);
+    JUnitTestCase.assertNotNull(expression.parameters);
+    JUnitTestCase.assertNotNull(expression.body);
+  }
+  void test_parsePrimaryExpression_hex() {
+    String hexLiteral = "3F";
+    IntegerLiteral literal = ParserTestCase.parse4("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", []);
+    JUnitTestCase.assertNotNull(identifier);
+  }
+  void test_parsePrimaryExpression_int() {
+    String intLiteral = "472";
+    IntegerLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", intLiteral, []);
+    JUnitTestCase.assertNotNull(literal.literal);
+    JUnitTestCase.assertEquals(int.parse(intLiteral), literal.value);
+  }
+  void test_parsePrimaryExpression_listLiteral() {
+    ListLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "[ ]", []);
+    JUnitTestCase.assertNotNull(literal);
+  }
+  void test_parsePrimaryExpression_listLiteral_index() {
+    ListLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "[]", []);
+    JUnitTestCase.assertNotNull(literal);
+  }
+  void test_parsePrimaryExpression_listLiteral_typed() {
+    ListLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "<A>[ ]", []);
+    JUnitTestCase.assertNotNull(literal.typeArguments);
+    EngineTestCase.assertSize(1, literal.typeArguments.arguments);
+  }
+  void test_parsePrimaryExpression_mapLiteral() {
+    MapLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "{}", []);
+    JUnitTestCase.assertNotNull(literal);
+  }
+  void test_parsePrimaryExpression_mapLiteral_typed() {
+    MapLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "<A>{}", []);
+    JUnitTestCase.assertNotNull(literal.typeArguments);
+    EngineTestCase.assertSize(1, literal.typeArguments.arguments);
+  }
+  void test_parsePrimaryExpression_new() {
+    InstanceCreationExpression expression = ParserTestCase.parse4("parsePrimaryExpression", "new A()", []);
+    JUnitTestCase.assertNotNull(expression);
+  }
+  void test_parsePrimaryExpression_null() {
+    NullLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "null", []);
+    JUnitTestCase.assertNotNull(literal.literal);
+  }
+  void test_parsePrimaryExpression_parenthesized() {
+    ParenthesizedExpression expression = ParserTestCase.parse4("parsePrimaryExpression", "()", []);
+    JUnitTestCase.assertNotNull(expression);
+  }
+  void test_parsePrimaryExpression_string() {
+    SimpleStringLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "\"string\"", []);
+    JUnitTestCase.assertFalse(literal.isMultiline());
+    JUnitTestCase.assertEquals("string", literal.value);
+  }
+  void test_parsePrimaryExpression_super() {
+    PropertyAccess propertyAccess = ParserTestCase.parse4("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", []);
+    JUnitTestCase.assertNotNull(expression.keyword);
+  }
+  void test_parsePrimaryExpression_true() {
+    BooleanLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "true", []);
+    JUnitTestCase.assertNotNull(literal.literal);
+    JUnitTestCase.assertTrue(literal.value);
+  }
+  void test_Parser() {
+    JUnitTestCase.assertNotNull(new Parser(null, null));
+  }
+  void test_parseRedirectingConstructorInvocation_named() {
+    RedirectingConstructorInvocation invocation = ParserTestCase.parse4("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()", []);
+    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", []);
+    JUnitTestCase.assertNotNull(expression.expression);
+    JUnitTestCase.assertNotNull(expression.asOperator);
+    JUnitTestCase.assertNotNull(expression.type);
+  }
+  void test_parseRelationalExpression_is() {
+    IsExpression expression = ParserTestCase.parse4("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", []);
+    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", []);
+    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", []);
+    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;", []);
+    JUnitTestCase.assertNotNull(statement.keyword);
+    JUnitTestCase.assertNull(statement.expression);
+    JUnitTestCase.assertNotNull(statement.semicolon);
+  }
+  void test_parseReturnStatement_value() {
+    ReturnStatement statement = ParserTestCase.parse4("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>", []);
+    JUnitTestCase.assertNotNull(typeName.name);
+    JUnitTestCase.assertNotNull(typeName.typeArguments);
+  }
+  void test_parseReturnType_void() {
+    TypeName typeName = ParserTestCase.parse4("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);
+    MethodDeclaration method = ParserTestCase.parse("parseSetter", <Object> [commentAndMetadata(comment, []), null, null, returnType], "set a(var x);");
+    JUnitTestCase.assertNotNull(method.body);
+    JUnitTestCase.assertEquals(comment, method.documentationComment);
+    JUnitTestCase.assertNull(method.externalKeyword);
+    JUnitTestCase.assertNull(method.modifierKeyword);
+    JUnitTestCase.assertNotNull(method.name);
+    JUnitTestCase.assertNull(method.operatorKeyword);
+    JUnitTestCase.assertNotNull(method.parameters);
+    JUnitTestCase.assertNotNull(method.propertyKeyword);
+    JUnitTestCase.assertEquals(returnType, method.returnType);
+  }
+  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);
+    MethodDeclaration method = ParserTestCase.parse("parseSetter", <Object> [commentAndMetadata(comment, []), null, staticKeyword, returnType], "set a(var x) {}");
+    JUnitTestCase.assertNotNull(method.body);
+    JUnitTestCase.assertEquals(comment, method.documentationComment);
+    JUnitTestCase.assertNull(method.externalKeyword);
+    JUnitTestCase.assertEquals(staticKeyword, method.modifierKeyword);
+    JUnitTestCase.assertNotNull(method.name);
+    JUnitTestCase.assertNull(method.operatorKeyword);
+    JUnitTestCase.assertNotNull(method.parameters);
+    JUnitTestCase.assertNotNull(method.propertyKeyword);
+    JUnitTestCase.assertEquals(returnType, method.returnType);
+  }
+  void test_parseShiftExpression_normal() {
+    BinaryExpression expression = ParserTestCase.parse4("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", []);
+    JUnitTestCase.assertNotNull(expression.leftOperand);
+    JUnitTestCase.assertNotNull(expression.operator);
+    JUnitTestCase.assertEquals(TokenType.LT_LT, expression.operator.type);
+    JUnitTestCase.assertNotNull(expression.rightOperand);
+  }
+  void test_parseSimpleIdentifier_builtInIdentifier() {
+    String lexeme = "as";
+    SimpleIdentifier identifier = ParserTestCase.parse4("parseSimpleIdentifier", lexeme, []);
+    JUnitTestCase.assertNotNull(identifier.token);
+    JUnitTestCase.assertEquals(lexeme, identifier.name);
+  }
+  void test_parseSimpleIdentifier_normalIdentifier() {
+    String lexeme = "foo";
+    SimpleIdentifier identifier = ParserTestCase.parse4("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) {};", []);
+    JUnitTestCase.assertNotNull(statement.functionDeclaration);
+  }
+  void test_parseStatement_mulipleLabels() {
+    LabeledStatement statement = ParserTestCase.parse4("parseStatement", "l: m: return x;", []);
+    EngineTestCase.assertSize(2, statement.labels);
+    JUnitTestCase.assertNotNull(statement.statement);
+  }
+  void test_parseStatement_noLabels() {
+    ParserTestCase.parse4("parseStatement", "return x;", []);
+  }
+  void test_parseStatement_singleLabel() {
+    LabeledStatement statement = ParserTestCase.parse4("parseStatement", "l: return x;", []);
+    EngineTestCase.assertSize(1, statement.labels);
+    JUnitTestCase.assertNotNull(statement.statement);
+  }
+  void test_parseStatements_multiple() {
+    List<Statement> statements = ParserTestCase.parseStatements("return; return;", 2, []);
+    EngineTestCase.assertSize(2, statements);
+  }
+  void test_parseStatements_single() {
+    List<Statement> statements = ParserTestCase.parseStatements("return;", 1, []);
+    EngineTestCase.assertSize(1, statements);
+  }
+  void test_parseStringLiteral_adjacent() {
+    AdjacentStrings literal = ParserTestCase.parse4("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);
+  }
+  void test_parseStringLiteral_interpolated() {
+    StringInterpolation literal = ParserTestCase.parse4("parseStringLiteral", "'a \${b} c \$this d'", []);
+    NodeList<InterpolationElement> elements2 = literal.elements;
+    EngineTestCase.assertSize(5, elements2);
+    JUnitTestCase.assertTrue(elements2[0] is InterpolationString);
+    JUnitTestCase.assertTrue(elements2[1] is InterpolationExpression);
+    JUnitTestCase.assertTrue(elements2[2] is InterpolationString);
+    JUnitTestCase.assertTrue(elements2[3] is InterpolationExpression);
+    JUnitTestCase.assertTrue(elements2[4] is InterpolationString);
+  }
+  void test_parseStringLiteral_single() {
+    SimpleStringLiteral literal = ParserTestCase.parse4("parseStringLiteral", "'a'", []);
+    JUnitTestCase.assertNotNull(literal.literal);
+    JUnitTestCase.assertEquals("a", literal.value);
+  }
+  void test_parseSuperConstructorInvocation_named() {
+    SuperConstructorInvocation invocation = ParserTestCase.parse4("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()", []);
+    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';}", []);
+    JUnitTestCase.assertNotNull(statement.keyword);
+    JUnitTestCase.assertNotNull(statement.leftParenthesis);
+    JUnitTestCase.assertNotNull(statement.expression);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.leftBracket);
+    EngineTestCase.assertSize(1, statement.members);
+    JUnitTestCase.assertNotNull(statement.rightBracket);
+  }
+  void test_parseSwitchStatement_empty() {
+    SwitchStatement statement = ParserTestCase.parse4("parseSwitchStatement", "switch (a) {}", []);
+    JUnitTestCase.assertNotNull(statement.keyword);
+    JUnitTestCase.assertNotNull(statement.leftParenthesis);
+    JUnitTestCase.assertNotNull(statement.expression);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.leftBracket);
+    EngineTestCase.assertSize(0, statement.members);
+    JUnitTestCase.assertNotNull(statement.rightBracket);
+  }
+  void test_parseSwitchStatement_labeledCase() {
+    SwitchStatement statement = ParserTestCase.parse4("parseSwitchStatement", "switch (a) {l1: l2: l3: case(1):}", []);
+    JUnitTestCase.assertNotNull(statement.keyword);
+    JUnitTestCase.assertNotNull(statement.leftParenthesis);
+    JUnitTestCase.assertNotNull(statement.expression);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.leftBracket);
+    EngineTestCase.assertSize(1, statement.members);
+    EngineTestCase.assertSize(3, statement.members[0].labels);
+    JUnitTestCase.assertNotNull(statement.rightBracket);
+  }
+  void test_parseSwitchStatement_labeledStatementInCase() {
+    SwitchStatement statement = ParserTestCase.parse4("parseSwitchStatement", "switch (a) {case 0: f(); l1: g(); break;}", []);
+    JUnitTestCase.assertNotNull(statement.keyword);
+    JUnitTestCase.assertNotNull(statement.leftParenthesis);
+    JUnitTestCase.assertNotNull(statement.expression);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.leftBracket);
+    EngineTestCase.assertSize(1, statement.members);
+    EngineTestCase.assertSize(3, statement.members[0].statements);
+    JUnitTestCase.assertNotNull(statement.rightBracket);
+  }
+  void test_parseThrowExpression_expression() {
+    ThrowExpression statement = ParserTestCase.parse4("parseThrowExpression", "throw x;", []);
+    JUnitTestCase.assertNotNull(statement.keyword);
+    JUnitTestCase.assertNotNull(statement.expression);
+  }
+  void test_parseThrowExpression_noExpression() {
+    ThrowExpression statement = ParserTestCase.parse4("parseThrowExpression", "throw;", []);
+    JUnitTestCase.assertNotNull(statement.keyword);
+    JUnitTestCase.assertNull(statement.expression);
+  }
+  void test_parseThrowExpressionWithoutCascade_expression() {
+    ThrowExpression statement = ParserTestCase.parse4("parseThrowExpressionWithoutCascade", "throw x;", []);
+    JUnitTestCase.assertNotNull(statement.keyword);
+    JUnitTestCase.assertNotNull(statement.expression);
+  }
+  void test_parseThrowExpressionWithoutCascade_noExpression() {
+    ThrowExpression statement = ParserTestCase.parse4("parseThrowExpressionWithoutCascade", "throw;", []);
+    JUnitTestCase.assertNotNull(statement.keyword);
+    JUnitTestCase.assertNull(statement.expression);
+  }
+  void test_parseTryStatement_catch() {
+    TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} catch (e) {}", []);
+    JUnitTestCase.assertNotNull(statement.tryKeyword);
+    JUnitTestCase.assertNotNull(statement.body);
+    NodeList<CatchClause> catchClauses2 = statement.catchClauses;
+    EngineTestCase.assertSize(1, catchClauses2);
+    CatchClause clause = catchClauses2[0];
+    JUnitTestCase.assertNull(clause.onKeyword);
+    JUnitTestCase.assertNull(clause.exceptionType);
+    JUnitTestCase.assertNotNull(clause.catchKeyword);
+    JUnitTestCase.assertNotNull(clause.exceptionParameter);
+    JUnitTestCase.assertNull(clause.comma);
+    JUnitTestCase.assertNull(clause.stackTraceParameter);
+    JUnitTestCase.assertNotNull(clause.body);
+    JUnitTestCase.assertNull(statement.finallyKeyword);
+    JUnitTestCase.assertNull(statement.finallyClause);
+  }
+  void test_parseTryStatement_catch_finally() {
+    TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} catch (e, s) {} finally {}", []);
+    JUnitTestCase.assertNotNull(statement.tryKeyword);
+    JUnitTestCase.assertNotNull(statement.body);
+    NodeList<CatchClause> catchClauses3 = statement.catchClauses;
+    EngineTestCase.assertSize(1, catchClauses3);
+    CatchClause clause = catchClauses3[0];
+    JUnitTestCase.assertNull(clause.onKeyword);
+    JUnitTestCase.assertNull(clause.exceptionType);
+    JUnitTestCase.assertNotNull(clause.catchKeyword);
+    JUnitTestCase.assertNotNull(clause.exceptionParameter);
+    JUnitTestCase.assertNotNull(clause.comma);
+    JUnitTestCase.assertNotNull(clause.stackTraceParameter);
+    JUnitTestCase.assertNotNull(clause.body);
+    JUnitTestCase.assertNotNull(statement.finallyKeyword);
+    JUnitTestCase.assertNotNull(statement.finallyClause);
+  }
+  void test_parseTryStatement_finally() {
+    TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} finally {}", []);
+    JUnitTestCase.assertNotNull(statement.tryKeyword);
+    JUnitTestCase.assertNotNull(statement.body);
+    EngineTestCase.assertSize(0, statement.catchClauses);
+    JUnitTestCase.assertNotNull(statement.finallyKeyword);
+    JUnitTestCase.assertNotNull(statement.finallyClause);
+  }
+  void test_parseTryStatement_multiple() {
+    TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} on NPE catch (e) {} on Error {} catch (e) {}", []);
+    JUnitTestCase.assertNotNull(statement.tryKeyword);
+    JUnitTestCase.assertNotNull(statement.body);
+    EngineTestCase.assertSize(3, statement.catchClauses);
+    JUnitTestCase.assertNull(statement.finallyKeyword);
+    JUnitTestCase.assertNull(statement.finallyClause);
+  }
+  void test_parseTryStatement_on() {
+    TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} on Error {}", []);
+    JUnitTestCase.assertNotNull(statement.tryKeyword);
+    JUnitTestCase.assertNotNull(statement.body);
+    NodeList<CatchClause> catchClauses4 = statement.catchClauses;
+    EngineTestCase.assertSize(1, catchClauses4);
+    CatchClause clause = catchClauses4[0];
+    JUnitTestCase.assertNotNull(clause.onKeyword);
+    JUnitTestCase.assertNotNull(clause.exceptionType);
+    JUnitTestCase.assertNull(clause.catchKeyword);
+    JUnitTestCase.assertNull(clause.exceptionParameter);
+    JUnitTestCase.assertNull(clause.comma);
+    JUnitTestCase.assertNull(clause.stackTraceParameter);
+    JUnitTestCase.assertNotNull(clause.body);
+    JUnitTestCase.assertNull(statement.finallyKeyword);
+    JUnitTestCase.assertNull(statement.finallyClause);
+  }
+  void test_parseTryStatement_on_catch() {
+    TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} on Error catch (e, s) {}", []);
+    JUnitTestCase.assertNotNull(statement.tryKeyword);
+    JUnitTestCase.assertNotNull(statement.body);
+    NodeList<CatchClause> catchClauses5 = statement.catchClauses;
+    EngineTestCase.assertSize(1, catchClauses5);
+    CatchClause clause = catchClauses5[0];
+    JUnitTestCase.assertNotNull(clause.onKeyword);
+    JUnitTestCase.assertNotNull(clause.exceptionType);
+    JUnitTestCase.assertNotNull(clause.catchKeyword);
+    JUnitTestCase.assertNotNull(clause.exceptionParameter);
+    JUnitTestCase.assertNotNull(clause.comma);
+    JUnitTestCase.assertNotNull(clause.stackTraceParameter);
+    JUnitTestCase.assertNotNull(clause.body);
+    JUnitTestCase.assertNull(statement.finallyKeyword);
+    JUnitTestCase.assertNull(statement.finallyClause);
+  }
+  void test_parseTryStatement_on_catch_finally() {
+    TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {} on Error catch (e, s) {} finally {}", []);
+    JUnitTestCase.assertNotNull(statement.tryKeyword);
+    JUnitTestCase.assertNotNull(statement.body);
+    NodeList<CatchClause> catchClauses6 = statement.catchClauses;
+    EngineTestCase.assertSize(1, catchClauses6);
+    CatchClause clause = catchClauses6[0];
+    JUnitTestCase.assertNotNull(clause.onKeyword);
+    JUnitTestCase.assertNotNull(clause.exceptionType);
+    JUnitTestCase.assertNotNull(clause.catchKeyword);
+    JUnitTestCase.assertNotNull(clause.exceptionParameter);
+    JUnitTestCase.assertNotNull(clause.comma);
+    JUnitTestCase.assertNotNull(clause.stackTraceParameter);
+    JUnitTestCase.assertNotNull(clause.body);
+    JUnitTestCase.assertNotNull(statement.finallyKeyword);
+    JUnitTestCase.assertNotNull(statement.finallyClause);
+  }
+  void test_parseTypeAlias_noParameters() {
+    FunctionTypeAlias typeAlias = ParserTestCase.parse("parseTypeAlias", <Object> [emptyCommentAndMetadata()], "typedef bool F();");
+    JUnitTestCase.assertNotNull(typeAlias.keyword);
+    JUnitTestCase.assertNotNull(typeAlias.name);
+    JUnitTestCase.assertNotNull(typeAlias.parameters);
+    JUnitTestCase.assertNotNull(typeAlias.returnType);
+    JUnitTestCase.assertNotNull(typeAlias.semicolon);
+    JUnitTestCase.assertNull(typeAlias.typeParameters);
+  }
+  void test_parseTypeAlias_noReturnType() {
+    FunctionTypeAlias typeAlias = ParserTestCase.parse("parseTypeAlias", <Object> [emptyCommentAndMetadata()], "typedef F();");
+    JUnitTestCase.assertNotNull(typeAlias.keyword);
+    JUnitTestCase.assertNotNull(typeAlias.name);
+    JUnitTestCase.assertNotNull(typeAlias.parameters);
+    JUnitTestCase.assertNull(typeAlias.returnType);
+    JUnitTestCase.assertNotNull(typeAlias.semicolon);
+    JUnitTestCase.assertNull(typeAlias.typeParameters);
+  }
+  void test_parseTypeAlias_parameterizedReturnType() {
+    FunctionTypeAlias typeAlias = ParserTestCase.parse("parseTypeAlias", <Object> [emptyCommentAndMetadata()], "typedef A<B> F();");
+    JUnitTestCase.assertNotNull(typeAlias.keyword);
+    JUnitTestCase.assertNotNull(typeAlias.name);
+    JUnitTestCase.assertNotNull(typeAlias.parameters);
+    JUnitTestCase.assertNotNull(typeAlias.returnType);
+    JUnitTestCase.assertNotNull(typeAlias.semicolon);
+    JUnitTestCase.assertNull(typeAlias.typeParameters);
+  }
+  void test_parseTypeAlias_parameters() {
+    FunctionTypeAlias typeAlias = ParserTestCase.parse("parseTypeAlias", <Object> [emptyCommentAndMetadata()], "typedef bool F(Object value);");
+    JUnitTestCase.assertNotNull(typeAlias.keyword);
+    JUnitTestCase.assertNotNull(typeAlias.name);
+    JUnitTestCase.assertNotNull(typeAlias.parameters);
+    JUnitTestCase.assertNotNull(typeAlias.returnType);
+    JUnitTestCase.assertNotNull(typeAlias.semicolon);
+    JUnitTestCase.assertNull(typeAlias.typeParameters);
+  }
+  void test_parseTypeAlias_typeParameters() {
+    FunctionTypeAlias typeAlias = ParserTestCase.parse("parseTypeAlias", <Object> [emptyCommentAndMetadata()], "typedef bool F<E>();");
+    JUnitTestCase.assertNotNull(typeAlias.keyword);
+    JUnitTestCase.assertNotNull(typeAlias.name);
+    JUnitTestCase.assertNotNull(typeAlias.parameters);
+    JUnitTestCase.assertNotNull(typeAlias.returnType);
+    JUnitTestCase.assertNotNull(typeAlias.semicolon);
+    JUnitTestCase.assertNotNull(typeAlias.typeParameters);
+  }
+  void test_parseTypeAlias_voidReturnType() {
+    FunctionTypeAlias typeAlias = ParserTestCase.parse("parseTypeAlias", <Object> [emptyCommentAndMetadata()], "typedef void F();");
+    JUnitTestCase.assertNotNull(typeAlias.keyword);
+    JUnitTestCase.assertNotNull(typeAlias.name);
+    JUnitTestCase.assertNotNull(typeAlias.parameters);
+    JUnitTestCase.assertNotNull(typeAlias.returnType);
+    JUnitTestCase.assertNotNull(typeAlias.semicolon);
+    JUnitTestCase.assertNull(typeAlias.typeParameters);
+  }
+  void test_parseTypeArgumentList_multiple() {
+    TypeArgumentList argumentList = ParserTestCase.parse4("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>>", []);
+    JUnitTestCase.assertNotNull(argumentList.leftBracket);
+    EngineTestCase.assertSize(1, argumentList.arguments);
+    TypeName argument = argumentList.arguments[0];
+    JUnitTestCase.assertNotNull(argument);
+    TypeArgumentList innerList = argument.typeArguments;
+    JUnitTestCase.assertNotNull(innerList);
+    EngineTestCase.assertSize(1, innerList.arguments);
+    JUnitTestCase.assertNotNull(argumentList.rightBracket);
+  }
+  void test_parseTypeArgumentList_single() {
+    TypeArgumentList argumentList = ParserTestCase.parse4("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>", []);
+    JUnitTestCase.assertNotNull(typeName.name);
+    JUnitTestCase.assertNotNull(typeName.typeArguments);
+  }
+  void test_parseTypeName_simple() {
+    TypeName typeName = ParserTestCase.parse4("parseTypeName", "int", []);
+    JUnitTestCase.assertNotNull(typeName.name);
+    JUnitTestCase.assertNull(typeName.typeArguments);
+  }
+  void test_parseTypeParameter_bounded() {
+    TypeParameter parameter = ParserTestCase.parse4("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", []);
+    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>", []);
+    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>>=", []);
+    JUnitTestCase.assertNotNull(parameterList.leftBracket);
+    JUnitTestCase.assertNotNull(parameterList.rightBracket);
+    EngineTestCase.assertSize(1, parameterList.typeParameters);
+  }
+  void test_parseTypeParameterList_single() {
+    TypeParameterList parameterList = ParserTestCase.parse4("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>=", []);
+    JUnitTestCase.assertNotNull(parameterList.leftBracket);
+    JUnitTestCase.assertNotNull(parameterList.rightBracket);
+    EngineTestCase.assertSize(1, parameterList.typeParameters);
+  }
+  void test_parseUnaryExpression_decrement_normal() {
+    PrefixExpression expression = ParserTestCase.parse4("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", []);
+    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;
+    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", []);
+    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", []);
+    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", []);
+    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", []);
+    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", []);
+    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", []);
+    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", []);
+    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", []);
+    JUnitTestCase.assertNotNull(declaration.name);
+    JUnitTestCase.assertNotNull(declaration.equals);
+    JUnitTestCase.assertNotNull(declaration.initializer);
+  }
+  void test_parseVariableDeclaration_noEquals() {
+    VariableDeclaration declaration = ParserTestCase.parse4("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", []);
+    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", []);
+    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", []);
+    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", []);
+    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", []);
+    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", []);
+    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", []);
+    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", []);
+    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);
+    VariableDeclarationList declarationList = ParserTestCase.parse("parseVariableDeclarationList", <Object> [null, type], "a");
+    JUnitTestCase.assertNull(declarationList.keyword);
+    JUnitTestCase.assertEquals(type, declarationList.type);
+    EngineTestCase.assertSize(1, declarationList.variables);
+  }
+  void test_parseVariableDeclarationList2_var() {
+    Token keyword = TokenFactory.token(Keyword.VAR);
+    VariableDeclarationList declarationList = ParserTestCase.parse("parseVariableDeclarationList", <Object> [keyword, null], "a, b, c");
+    JUnitTestCase.assertEquals(keyword, declarationList.keyword);
+    JUnitTestCase.assertNull(declarationList.type);
+    EngineTestCase.assertSize(3, declarationList.variables);
+  }
+  void test_parseVariableDeclarationStatement_multiple() {
+    VariableDeclarationStatement statement = ParserTestCase.parse4("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;", []);
+    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) {}", []);
+    JUnitTestCase.assertNotNull(statement.keyword);
+    JUnitTestCase.assertNotNull(statement.leftParenthesis);
+    JUnitTestCase.assertNotNull(statement.condition);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.body);
+  }
+  void test_parseWithClause_multiple() {
+    WithClause clause = ParserTestCase.parse4("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", []);
+    JUnitTestCase.assertNotNull(clause.withKeyword);
+    EngineTestCase.assertSize(1, clause.mixinTypes);
+  }
+  void test_skipPrefixedIdentifier_invalid() {
+    Token following = skip("skipPrefixedIdentifier", "+");
+    JUnitTestCase.assertNull(following);
+  }
+  void test_skipPrefixedIdentifier_notPrefixed() {
+    Token following = skip("skipPrefixedIdentifier", "a +");
+    JUnitTestCase.assertNotNull(following);
+    JUnitTestCase.assertEquals(TokenType.PLUS, following.type);
+  }
+  void test_skipPrefixedIdentifier_prefixed() {
+    Token following = skip("skipPrefixedIdentifier", "a.b +");
+    JUnitTestCase.assertNotNull(following);
+    JUnitTestCase.assertEquals(TokenType.PLUS, following.type);
+  }
+  void test_skipReturnType_invalid() {
+    Token following = skip("skipReturnType", "+");
+    JUnitTestCase.assertNull(following);
+  }
+  void test_skipReturnType_type() {
+    Token following = skip("skipReturnType", "C +");
+    JUnitTestCase.assertNotNull(following);
+    JUnitTestCase.assertEquals(TokenType.PLUS, following.type);
+  }
+  void test_skipReturnType_void() {
+    Token following = skip("skipReturnType", "void +");
+    JUnitTestCase.assertNotNull(following);
+    JUnitTestCase.assertEquals(TokenType.PLUS, following.type);
+  }
+  void test_skipSimpleIdentifier_identifier() {
+    Token following = skip("skipSimpleIdentifier", "i +");
+    JUnitTestCase.assertNotNull(following);
+    JUnitTestCase.assertEquals(TokenType.PLUS, following.type);
+  }
+  void test_skipSimpleIdentifier_invalid() {
+    Token following = skip("skipSimpleIdentifier", "9 +");
+    JUnitTestCase.assertNull(following);
+  }
+  void test_skipSimpleIdentifier_pseudoKeyword() {
+    Token following = skip("skipSimpleIdentifier", "as +");
+    JUnitTestCase.assertNotNull(following);
+    JUnitTestCase.assertEquals(TokenType.PLUS, following.type);
+  }
+  void test_skipStringLiteral_adjacent() {
+    Token following = skip("skipStringLiteral", "'a' 'b' +");
+    JUnitTestCase.assertNotNull(following);
+    JUnitTestCase.assertEquals(TokenType.PLUS, following.type);
+  }
+  void test_skipStringLiteral_interpolated() {
+    Token following = skip("skipStringLiteral", "'a\${b}c' +");
+    JUnitTestCase.assertNotNull(following);
+    JUnitTestCase.assertEquals(TokenType.PLUS, following.type);
+  }
+  void test_skipStringLiteral_invalid() {
+    Token following = skip("skipStringLiteral", "a");
+    JUnitTestCase.assertNull(following);
+  }
+  void test_skipStringLiteral_single() {
+    Token following = skip("skipStringLiteral", "'a' +");
+    JUnitTestCase.assertNotNull(following);
+    JUnitTestCase.assertEquals(TokenType.PLUS, following.type);
+  }
+  void test_skipTypeArgumentList_invalid() {
+    Token following = skip("skipTypeArgumentList", "+");
+    JUnitTestCase.assertNull(following);
+  }
+  void test_skipTypeArgumentList_multiple() {
+    Token following = skip("skipTypeArgumentList", "<E, F, G> +");
+    JUnitTestCase.assertNotNull(following);
+    JUnitTestCase.assertEquals(TokenType.PLUS, following.type);
+  }
+  void test_skipTypeArgumentList_single() {
+    Token following = skip("skipTypeArgumentList", "<E> +");
+    JUnitTestCase.assertNotNull(following);
+    JUnitTestCase.assertEquals(TokenType.PLUS, following.type);
+  }
+  void test_skipTypeName_invalid() {
+    Token following = skip("skipTypeName", "+");
+    JUnitTestCase.assertNull(following);
+  }
+  void test_skipTypeName_parameterized() {
+    Token following = skip("skipTypeName", "C<E<F<G>>> +");
+    JUnitTestCase.assertNotNull(following);
+    JUnitTestCase.assertEquals(TokenType.PLUS, following.type);
+  }
+  void test_skipTypeName_simple() {
+    Token following = skip("skipTypeName", "C +");
+    JUnitTestCase.assertNotNull(following);
+    JUnitTestCase.assertEquals(TokenType.PLUS, following.type);
+  }
+  /**
+   * Invoke the method {@link Parser#computeStringValue(String)} with the given argument.
+   * @param lexeme the argument to the method
+   * @return the result of invoking the method
+   * @throws Exception if the method could not be invoked or throws an exception
+   */
+  String computeStringValue(String lexeme) {
+    AnalysisErrorListener listener = new AnalysisErrorListener_4();
+    Parser parser = new Parser(null, listener);
+    return invokeParserMethodImpl(parser, "computeStringValue", <Object> [lexeme], null) as String;
+  }
+  /**
+   * Invoke the method {@link Parser#createSyntheticIdentifier()} with the parser set to the token
+   * stream produced by scanning the given source.
+   * @param source the source to be scanned to produce the token stream being tested
+   * @return the result of invoking the method
+   * @throws Exception if the method could not be invoked or throws an exception
+   */
+  SimpleIdentifier createSyntheticIdentifier() {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    return ParserTestCase.invokeParserMethod2("createSyntheticIdentifier", "", listener);
+  }
+  /**
+   * Invoke the method {@link Parser#createSyntheticIdentifier()} with the parser set to the token
+   * stream produced by scanning the given source.
+   * @param source the source to be scanned to produce the token stream being tested
+   * @return the result of invoking the method
+   * @throws Exception if the method could not be invoked or throws an exception
+   */
+  SimpleStringLiteral createSyntheticStringLiteral() {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    return ParserTestCase.invokeParserMethod2("createSyntheticStringLiteral", "", listener);
+  }
+  /**
+   * Invoke the method {@link Parser#isFunctionDeclaration()} with the parser set to the token
+   * stream produced by scanning the given source.
+   * @param source the source to be scanned to produce the token stream being tested
+   * @return the result of invoking the method
+   * @throws Exception if the method could not be invoked or throws an exception
+   */
+  bool isFunctionDeclaration(String source) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    return ParserTestCase.invokeParserMethod2("isFunctionDeclaration", source, listener);
+  }
+  /**
+   * Invoke the method {@link Parser#isFunctionExpression()} with the parser set to the token stream
+   * produced by scanning the given source.
+   * @param source the source to be scanned to produce the token stream being tested
+   * @return the result of invoking the method
+   * @throws Exception if the method could not be invoked or throws an exception
+   */
+  bool isFunctionExpression(String source) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    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;
+  }
+  /**
+   * Invoke the method {@link Parser#isInitializedVariableDeclaration()} with the parser set to the
+   * token stream produced by scanning the given source.
+   * @param source the source to be scanned to produce the token stream being tested
+   * @return the result of invoking the method
+   * @throws Exception if the method could not be invoked or throws an exception
+   */
+  bool isInitializedVariableDeclaration(String source) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    return ParserTestCase.invokeParserMethod2("isInitializedVariableDeclaration", source, listener);
+  }
+  /**
+   * Invoke the method {@link Parser#isSwitchMember()} with the parser set to the token stream
+   * produced by scanning the given source.
+   * @param source the source to be scanned to produce the token stream being tested
+   * @return the result of invoking the method
+   * @throws Exception if the method could not be invoked or throws an exception
+   */
+  bool isSwitchMember(String source) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    return ParserTestCase.invokeParserMethod2("isSwitchMember", source, listener);
+  }
+  /**
+   * Invoke a "skip" method in {@link Parser}. The method is assumed to take a token as it's
+   * parameter and is given the first token in the scanned source.
+   * @param methodName the name of the method that should be invoked
+   * @param source the source to be processed by the method
+   * @return the result of invoking the method
+   * @throws Exception if the method could not be invoked or throws an exception
+   * @throws AssertionFailedError if the result is {@code null}
+   */
+  Token skip(String methodName, String source) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    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;
+  }
+  static dartSuite() {
+    _ut.group('SimpleParserTest', () {
+      _ut.test('test_Parser', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_Parser);
+      });
+      _ut.test('test_computeStringValue_emptyInterpolationPrefix', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_computeStringValue_emptyInterpolationPrefix);
+      });
+      _ut.test('test_computeStringValue_escape_b', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_computeStringValue_escape_b);
+      });
+      _ut.test('test_computeStringValue_escape_f', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_computeStringValue_escape_f);
+      });
+      _ut.test('test_computeStringValue_escape_n', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_computeStringValue_escape_n);
+      });
+      _ut.test('test_computeStringValue_escape_notSpecial', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_computeStringValue_escape_notSpecial);
+      });
+      _ut.test('test_computeStringValue_escape_r', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_computeStringValue_escape_r);
+      });
+      _ut.test('test_computeStringValue_escape_t', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_computeStringValue_escape_t);
+      });
+      _ut.test('test_computeStringValue_escape_u_fixed', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_computeStringValue_escape_u_fixed);
+      });
+      _ut.test('test_computeStringValue_escape_u_variable', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_computeStringValue_escape_u_variable);
+      });
+      _ut.test('test_computeStringValue_escape_v', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_computeStringValue_escape_v);
+      });
+      _ut.test('test_computeStringValue_escape_x', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_computeStringValue_escape_x);
+      });
+      _ut.test('test_computeStringValue_noEscape_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_computeStringValue_noEscape_single);
+      });
+      _ut.test('test_computeStringValue_noEscape_triple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_computeStringValue_noEscape_triple);
+      });
+      _ut.test('test_computeStringValue_raw_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_computeStringValue_raw_single);
+      });
+      _ut.test('test_computeStringValue_raw_triple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_computeStringValue_raw_triple);
+      });
+      _ut.test('test_computeStringValue_raw_withEscape', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_computeStringValue_raw_withEscape);
+      });
+      _ut.test('test_createSyntheticIdentifier', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_createSyntheticIdentifier);
+      });
+      _ut.test('test_createSyntheticStringLiteral', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_createSyntheticStringLiteral);
+      });
+      _ut.test('test_isFunctionDeclaration_nameButNoReturn_block', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isFunctionDeclaration_nameButNoReturn_block);
+      });
+      _ut.test('test_isFunctionDeclaration_nameButNoReturn_expression', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isFunctionDeclaration_nameButNoReturn_expression);
+      });
+      _ut.test('test_isFunctionDeclaration_normalReturn_block', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isFunctionDeclaration_normalReturn_block);
+      });
+      _ut.test('test_isFunctionDeclaration_normalReturn_expression', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isFunctionDeclaration_normalReturn_expression);
+      });
+      _ut.test('test_isFunctionDeclaration_voidReturn_block', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isFunctionDeclaration_voidReturn_block);
+      });
+      _ut.test('test_isFunctionDeclaration_voidReturn_expression', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isFunctionDeclaration_voidReturn_expression);
+      });
+      _ut.test('test_isFunctionExpression_false_noBody', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isFunctionExpression_false_noBody);
+      });
+      _ut.test('test_isFunctionExpression_false_notParameters', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isFunctionExpression_false_notParameters);
+      });
+      _ut.test('test_isFunctionExpression_noName_block', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isFunctionExpression_noName_block);
+      });
+      _ut.test('test_isFunctionExpression_noName_expression', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isFunctionExpression_noName_expression);
+      });
+      _ut.test('test_isFunctionExpression_parameter_multiple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isFunctionExpression_parameter_multiple);
+      });
+      _ut.test('test_isFunctionExpression_parameter_named', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isFunctionExpression_parameter_named);
+      });
+      _ut.test('test_isFunctionExpression_parameter_optional', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isFunctionExpression_parameter_optional);
+      });
+      _ut.test('test_isFunctionExpression_parameter_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isFunctionExpression_parameter_single);
+      });
+      _ut.test('test_isFunctionExpression_parameter_typed', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isFunctionExpression_parameter_typed);
+      });
+      _ut.test('test_isInitializedVariableDeclaration_assignment', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isInitializedVariableDeclaration_assignment);
+      });
+      _ut.test('test_isInitializedVariableDeclaration_comparison', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isInitializedVariableDeclaration_comparison);
+      });
+      _ut.test('test_isInitializedVariableDeclaration_conditional', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isInitializedVariableDeclaration_conditional);
+      });
+      _ut.test('test_isInitializedVariableDeclaration_const_noType_initialized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isInitializedVariableDeclaration_const_noType_initialized);
+      });
+      _ut.test('test_isInitializedVariableDeclaration_const_noType_uninitialized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isInitializedVariableDeclaration_const_noType_uninitialized);
+      });
+      _ut.test('test_isInitializedVariableDeclaration_const_simpleType_uninitialized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isInitializedVariableDeclaration_const_simpleType_uninitialized);
+      });
+      _ut.test('test_isInitializedVariableDeclaration_final_noType_initialized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isInitializedVariableDeclaration_final_noType_initialized);
+      });
+      _ut.test('test_isInitializedVariableDeclaration_final_noType_uninitialized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isInitializedVariableDeclaration_final_noType_uninitialized);
+      });
+      _ut.test('test_isInitializedVariableDeclaration_final_simpleType_initialized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isInitializedVariableDeclaration_final_simpleType_initialized);
+      });
+      _ut.test('test_isInitializedVariableDeclaration_functionDeclaration_typed', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isInitializedVariableDeclaration_functionDeclaration_typed);
+      });
+      _ut.test('test_isInitializedVariableDeclaration_functionDeclaration_untyped', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isInitializedVariableDeclaration_functionDeclaration_untyped);
+      });
+      _ut.test('test_isInitializedVariableDeclaration_noType_initialized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isInitializedVariableDeclaration_noType_initialized);
+      });
+      _ut.test('test_isInitializedVariableDeclaration_noType_uninitialized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isInitializedVariableDeclaration_noType_uninitialized);
+      });
+      _ut.test('test_isInitializedVariableDeclaration_parameterizedType_initialized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isInitializedVariableDeclaration_parameterizedType_initialized);
+      });
+      _ut.test('test_isInitializedVariableDeclaration_parameterizedType_uninitialized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isInitializedVariableDeclaration_parameterizedType_uninitialized);
+      });
+      _ut.test('test_isInitializedVariableDeclaration_simpleType_initialized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isInitializedVariableDeclaration_simpleType_initialized);
+      });
+      _ut.test('test_isInitializedVariableDeclaration_simpleType_uninitialized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isInitializedVariableDeclaration_simpleType_uninitialized);
+      });
+      _ut.test('test_isSwitchMember_case_labeled', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isSwitchMember_case_labeled);
+      });
+      _ut.test('test_isSwitchMember_case_unlabeled', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isSwitchMember_case_unlabeled);
+      });
+      _ut.test('test_isSwitchMember_default_labeled', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isSwitchMember_default_labeled);
+      });
+      _ut.test('test_isSwitchMember_default_unlabeled', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isSwitchMember_default_unlabeled);
+      });
+      _ut.test('test_isSwitchMember_false', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_isSwitchMember_false);
+      });
+      _ut.test('test_parseAdditiveExpression_normal', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAdditiveExpression_normal);
+      });
+      _ut.test('test_parseAdditiveExpression_super', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAdditiveExpression_super);
+      });
+      _ut.test('test_parseAnnotation_n1', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAnnotation_n1);
+      });
+      _ut.test('test_parseAnnotation_n1_a', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAnnotation_n1_a);
+      });
+      _ut.test('test_parseAnnotation_n2', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAnnotation_n2);
+      });
+      _ut.test('test_parseAnnotation_n2_a', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAnnotation_n2_a);
+      });
+      _ut.test('test_parseAnnotation_n3', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAnnotation_n3);
+      });
+      _ut.test('test_parseAnnotation_n3_a', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAnnotation_n3_a);
+      });
+      _ut.test('test_parseArgumentDefinitionTest', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseArgumentDefinitionTest);
+      });
+      _ut.test('test_parseArgumentList_empty', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseArgumentList_empty);
+      });
+      _ut.test('test_parseArgumentList_mixed', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseArgumentList_mixed);
+      });
+      _ut.test('test_parseArgumentList_noNamed', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseArgumentList_noNamed);
+      });
+      _ut.test('test_parseArgumentList_onlyNamed', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseArgumentList_onlyNamed);
+      });
+      _ut.test('test_parseArgument_named', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseArgument_named);
+      });
+      _ut.test('test_parseArgument_unnamed', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseArgument_unnamed);
+      });
+      _ut.test('test_parseAssertStatement', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAssertStatement);
+      });
+      _ut.test('test_parseAssignableExpression_expression_args_dot', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAssignableExpression_expression_args_dot);
+      });
+      _ut.test('test_parseAssignableExpression_expression_dot', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAssignableExpression_expression_dot);
+      });
+      _ut.test('test_parseAssignableExpression_expression_index', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAssignableExpression_expression_index);
+      });
+      _ut.test('test_parseAssignableExpression_identifier', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAssignableExpression_identifier);
+      });
+      _ut.test('test_parseAssignableExpression_identifier_args_dot', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAssignableExpression_identifier_args_dot);
+      });
+      _ut.test('test_parseAssignableExpression_identifier_dot', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAssignableExpression_identifier_dot);
+      });
+      _ut.test('test_parseAssignableExpression_identifier_index', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAssignableExpression_identifier_index);
+      });
+      _ut.test('test_parseAssignableExpression_super_dot', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAssignableExpression_super_dot);
+      });
+      _ut.test('test_parseAssignableExpression_super_index', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAssignableExpression_super_index);
+      });
+      _ut.test('test_parseAssignableSelector_dot', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAssignableSelector_dot);
+      });
+      _ut.test('test_parseAssignableSelector_index', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAssignableSelector_index);
+      });
+      _ut.test('test_parseAssignableSelector_none', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAssignableSelector_none);
+      });
+      _ut.test('test_parseBitwiseAndExpression_normal', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseBitwiseAndExpression_normal);
+      });
+      _ut.test('test_parseBitwiseAndExpression_super', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseBitwiseAndExpression_super);
+      });
+      _ut.test('test_parseBitwiseOrExpression_normal', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseBitwiseOrExpression_normal);
+      });
+      _ut.test('test_parseBitwiseOrExpression_super', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseBitwiseOrExpression_super);
+      });
+      _ut.test('test_parseBitwiseXorExpression_normal', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseBitwiseXorExpression_normal);
+      });
+      _ut.test('test_parseBitwiseXorExpression_super', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseBitwiseXorExpression_super);
+      });
+      _ut.test('test_parseBlock_empty', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseBlock_empty);
+      });
+      _ut.test('test_parseBlock_nonEmpty', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseBlock_nonEmpty);
+      });
+      _ut.test('test_parseBreakStatement_label', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseBreakStatement_label);
+      });
+      _ut.test('test_parseBreakStatement_noLabel', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseBreakStatement_noLabel);
+      });
+      _ut.test('test_parseCascadeSection_i', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCascadeSection_i);
+      });
+      _ut.test('test_parseCascadeSection_ia', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCascadeSection_ia);
+      });
+      _ut.test('test_parseCascadeSection_p', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCascadeSection_p);
+      });
+      _ut.test('test_parseCascadeSection_p_assign', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCascadeSection_p_assign);
+      });
+      _ut.test('test_parseCascadeSection_p_builtIn', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCascadeSection_p_builtIn);
+      });
+      _ut.test('test_parseCascadeSection_pa', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCascadeSection_pa);
+      });
+      _ut.test('test_parseCascadeSection_paa', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCascadeSection_paa);
+      });
+      _ut.test('test_parseCascadeSection_paapaa', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCascadeSection_paapaa);
+      });
+      _ut.test('test_parseCascadeSection_pap', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCascadeSection_pap);
+      });
+      _ut.test('test_parseClassDeclaration_abstract', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassDeclaration_abstract);
+      });
+      _ut.test('test_parseClassDeclaration_empty', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassDeclaration_empty);
+      });
+      _ut.test('test_parseClassDeclaration_extends', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassDeclaration_extends);
+      });
+      _ut.test('test_parseClassDeclaration_extendsAndImplements', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassDeclaration_extendsAndImplements);
+      });
+      _ut.test('test_parseClassDeclaration_extendsAndWith', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassDeclaration_extendsAndWith);
+      });
+      _ut.test('test_parseClassDeclaration_extendsAndWithAndImplements', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassDeclaration_extendsAndWithAndImplements);
+      });
+      _ut.test('test_parseClassDeclaration_implements', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassDeclaration_implements);
+      });
+      _ut.test('test_parseClassDeclaration_nonEmpty', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassDeclaration_nonEmpty);
+      });
+      _ut.test('test_parseClassDeclaration_typeParameters', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassDeclaration_typeParameters);
+      });
+      _ut.test('test_parseClassMember_constructor_withInitializers', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_constructor_withInitializers);
+      });
+      _ut.test('test_parseClassMember_field_instance_prefixedType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_field_instance_prefixedType);
+      });
+      _ut.test('test_parseClassMember_field_namedGet', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_field_namedGet);
+      });
+      _ut.test('test_parseClassMember_field_namedOperator', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_field_namedOperator);
+      });
+      _ut.test('test_parseClassMember_field_namedSet', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_field_namedSet);
+      });
+      _ut.test('test_parseClassMember_getter_void', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_getter_void);
+      });
+      _ut.test('test_parseClassMember_method_external', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_method_external);
+      });
+      _ut.test('test_parseClassMember_method_external_withTypeAndArgs', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_method_external_withTypeAndArgs);
+      });
+      _ut.test('test_parseClassMember_method_get_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_method_get_noType);
+      });
+      _ut.test('test_parseClassMember_method_get_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_method_get_type);
+      });
+      _ut.test('test_parseClassMember_method_get_void', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_method_get_void);
+      });
+      _ut.test('test_parseClassMember_method_operator_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_method_operator_noType);
+      });
+      _ut.test('test_parseClassMember_method_operator_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_method_operator_type);
+      });
+      _ut.test('test_parseClassMember_method_operator_void', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_method_operator_void);
+      });
+      _ut.test('test_parseClassMember_method_returnType_parameterized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_method_returnType_parameterized);
+      });
+      _ut.test('test_parseClassMember_method_set_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_method_set_noType);
+      });
+      _ut.test('test_parseClassMember_method_set_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_method_set_type);
+      });
+      _ut.test('test_parseClassMember_method_set_void', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_method_set_void);
+      });
+      _ut.test('test_parseClassMember_operator_index', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_operator_index);
+      });
+      _ut.test('test_parseClassMember_operator_indexAssign', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_operator_indexAssign);
+      });
+      _ut.test('test_parseClassMember_redirectingFactory_const', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_redirectingFactory_const);
+      });
+      _ut.test('test_parseClassMember_redirectingFactory_nonConst', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseClassMember_redirectingFactory_nonConst);
+      });
+      _ut.test('test_parseCombinators_h', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCombinators_h);
+      });
+      _ut.test('test_parseCombinators_hs', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCombinators_hs);
+      });
+      _ut.test('test_parseCombinators_hshs', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCombinators_hshs);
+      });
+      _ut.test('test_parseCombinators_s', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCombinators_s);
+      });
+      _ut.test('test_parseCommentAndMetadata_c', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCommentAndMetadata_c);
+      });
+      _ut.test('test_parseCommentAndMetadata_cmc', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCommentAndMetadata_cmc);
+      });
+      _ut.test('test_parseCommentAndMetadata_cmcm', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCommentAndMetadata_cmcm);
+      });
+      _ut.test('test_parseCommentAndMetadata_cmm', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCommentAndMetadata_cmm);
+      });
+      _ut.test('test_parseCommentAndMetadata_m', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCommentAndMetadata_m);
+      });
+      _ut.test('test_parseCommentAndMetadata_mcm', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCommentAndMetadata_mcm);
+      });
+      _ut.test('test_parseCommentAndMetadata_mcmc', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCommentAndMetadata_mcmc);
+      });
+      _ut.test('test_parseCommentAndMetadata_mm', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCommentAndMetadata_mm);
+      });
+      _ut.test('test_parseCommentAndMetadata_none', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCommentAndMetadata_none);
+      });
+      _ut.test('test_parseCommentReference_new_prefixed', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCommentReference_new_prefixed);
+      });
+      _ut.test('test_parseCommentReference_new_simple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCommentReference_new_simple);
+      });
+      _ut.test('test_parseCommentReference_prefixed', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCommentReference_prefixed);
+      });
+      _ut.test('test_parseCommentReference_simple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCommentReference_simple);
+      });
+      _ut.test('test_parseCommentReferences_multiLine', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCommentReferences_multiLine);
+      });
+      _ut.test('test_parseCommentReferences_singleLine', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCommentReferences_singleLine);
+      });
+      _ut.test('test_parseCompilationUnitMember_class', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_class);
+      });
+      _ut.test('test_parseCompilationUnitMember_constVariable', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_constVariable);
+      });
+      _ut.test('test_parseCompilationUnitMember_finalVariable', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_finalVariable);
+      });
+      _ut.test('test_parseCompilationUnitMember_function_external_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_function_external_noType);
+      });
+      _ut.test('test_parseCompilationUnitMember_function_external_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_function_external_type);
+      });
+      _ut.test('test_parseCompilationUnitMember_function_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_function_noType);
+      });
+      _ut.test('test_parseCompilationUnitMember_function_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_function_type);
+      });
+      _ut.test('test_parseCompilationUnitMember_getter_external_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_getter_external_noType);
+      });
+      _ut.test('test_parseCompilationUnitMember_getter_external_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_getter_external_type);
+      });
+      _ut.test('test_parseCompilationUnitMember_getter_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_getter_noType);
+      });
+      _ut.test('test_parseCompilationUnitMember_getter_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_getter_type);
+      });
+      _ut.test('test_parseCompilationUnitMember_setter_external_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_setter_external_noType);
+      });
+      _ut.test('test_parseCompilationUnitMember_setter_external_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_setter_external_type);
+      });
+      _ut.test('test_parseCompilationUnitMember_setter_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_setter_noType);
+      });
+      _ut.test('test_parseCompilationUnitMember_setter_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_setter_type);
+      });
+      _ut.test('test_parseCompilationUnitMember_typedef_class_abstract', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_typedef_class_abstract);
+      });
+      _ut.test('test_parseCompilationUnitMember_typedef_class_generic', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_typedef_class_generic);
+      });
+      _ut.test('test_parseCompilationUnitMember_typedef_class_implements', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_typedef_class_implements);
+      });
+      _ut.test('test_parseCompilationUnitMember_typedef_class_noImplements', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_typedef_class_noImplements);
+      });
+      _ut.test('test_parseCompilationUnitMember_typedef_function', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_typedef_function);
+      });
+      _ut.test('test_parseCompilationUnitMember_variable', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnitMember_variable);
+      });
+      _ut.test('test_parseCompilationUnit_directives_multiple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnit_directives_multiple);
+      });
+      _ut.test('test_parseCompilationUnit_directives_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnit_directives_single);
+      });
+      _ut.test('test_parseCompilationUnit_empty', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnit_empty);
+      });
+      _ut.test('test_parseCompilationUnit_script', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnit_script);
+      });
+      _ut.test('test_parseCompilationUnit_topLevelDeclaration', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseCompilationUnit_topLevelDeclaration);
+      });
+      _ut.test('test_parseConditionalExpression', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseConditionalExpression);
+      });
+      _ut.test('test_parseConstExpression_instanceCreation', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseConstExpression_instanceCreation);
+      });
+      _ut.test('test_parseConstExpression_listLiteral_typed', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseConstExpression_listLiteral_typed);
+      });
+      _ut.test('test_parseConstExpression_listLiteral_untyped', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseConstExpression_listLiteral_untyped);
+      });
+      _ut.test('test_parseConstExpression_mapLiteral_typed', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseConstExpression_mapLiteral_typed);
+      });
+      _ut.test('test_parseConstExpression_mapLiteral_untyped', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseConstExpression_mapLiteral_untyped);
+      });
+      _ut.test('test_parseConstructor', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseConstructor);
+      });
+      _ut.test('test_parseConstructorFieldInitializer_qualified', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseConstructorFieldInitializer_qualified);
+      });
+      _ut.test('test_parseConstructorFieldInitializer_unqualified', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseConstructorFieldInitializer_unqualified);
+      });
+      _ut.test('test_parseConstructorName_named_noPrefix', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseConstructorName_named_noPrefix);
+      });
+      _ut.test('test_parseConstructorName_named_prefixed', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseConstructorName_named_prefixed);
+      });
+      _ut.test('test_parseConstructorName_unnamed_noPrefix', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseConstructorName_unnamed_noPrefix);
+      });
+      _ut.test('test_parseConstructorName_unnamed_prefixed', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseConstructorName_unnamed_prefixed);
+      });
+      _ut.test('test_parseContinueStatement_label', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseContinueStatement_label);
+      });
+      _ut.test('test_parseContinueStatement_noLabel', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseContinueStatement_noLabel);
+      });
+      _ut.test('test_parseDirective_export', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseDirective_export);
+      });
+      _ut.test('test_parseDirective_import', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseDirective_import);
+      });
+      _ut.test('test_parseDirective_library', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseDirective_library);
+      });
+      _ut.test('test_parseDirective_part', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseDirective_part);
+      });
+      _ut.test('test_parseDirective_partOf', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseDirective_partOf);
+      });
+      _ut.test('test_parseDoStatement', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseDoStatement);
+      });
+      _ut.test('test_parseDocumentationComment_block', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseDocumentationComment_block);
+      });
+      _ut.test('test_parseDocumentationComment_block_withReference', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseDocumentationComment_block_withReference);
+      });
+      _ut.test('test_parseDocumentationComment_endOfLine', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseDocumentationComment_endOfLine);
+      });
+      _ut.test('test_parseEmptyStatement', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseEmptyStatement);
+      });
+      _ut.test('test_parseEqualityExpression_normal', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseEqualityExpression_normal);
+      });
+      _ut.test('test_parseEqualityExpression_super', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseEqualityExpression_super);
+      });
+      _ut.test('test_parseExportDirective_hide', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseExportDirective_hide);
+      });
+      _ut.test('test_parseExportDirective_hide_show', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseExportDirective_hide_show);
+      });
+      _ut.test('test_parseExportDirective_noCombinator', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseExportDirective_noCombinator);
+      });
+      _ut.test('test_parseExportDirective_show', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseExportDirective_show);
+      });
+      _ut.test('test_parseExportDirective_show_hide', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseExportDirective_show_hide);
+      });
+      _ut.test('test_parseExpressionList_multiple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseExpressionList_multiple);
+      });
+      _ut.test('test_parseExpressionList_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseExpressionList_single);
+      });
+      _ut.test('test_parseExpressionWithoutCascade_assign', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseExpressionWithoutCascade_assign);
+      });
+      _ut.test('test_parseExpressionWithoutCascade_comparison', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseExpressionWithoutCascade_comparison);
+      });
+      _ut.test('test_parseExpressionWithoutCascade_superMethodInvocation', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseExpressionWithoutCascade_superMethodInvocation);
+      });
+      _ut.test('test_parseExpression_assign', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseExpression_assign);
+      });
+      _ut.test('test_parseExpression_comparison', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseExpression_comparison);
+      });
+      _ut.test('test_parseExpression_invokeFunctionExpression', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseExpression_invokeFunctionExpression);
+      });
+      _ut.test('test_parseExpression_superMethodInvocation', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseExpression_superMethodInvocation);
+      });
+      _ut.test('test_parseExtendsClause', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseExtendsClause);
+      });
+      _ut.test('test_parseFinalConstVarOrType_const_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFinalConstVarOrType_const_noType);
+      });
+      _ut.test('test_parseFinalConstVarOrType_const_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFinalConstVarOrType_const_type);
+      });
+      _ut.test('test_parseFinalConstVarOrType_final_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFinalConstVarOrType_final_noType);
+      });
+      _ut.test('test_parseFinalConstVarOrType_final_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFinalConstVarOrType_final_type);
+      });
+      _ut.test('test_parseFinalConstVarOrType_type_parameterized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFinalConstVarOrType_type_parameterized);
+      });
+      _ut.test('test_parseFinalConstVarOrType_type_prefixed', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFinalConstVarOrType_type_prefixed);
+      });
+      _ut.test('test_parseFinalConstVarOrType_type_prefixedAndParameterized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFinalConstVarOrType_type_prefixedAndParameterized);
+      });
+      _ut.test('test_parseFinalConstVarOrType_type_simple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFinalConstVarOrType_type_simple);
+      });
+      _ut.test('test_parseFinalConstVarOrType_var', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFinalConstVarOrType_var);
+      });
+      _ut.test('test_parseForStatement_each_identifier', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseForStatement_each_identifier);
+      });
+      _ut.test('test_parseForStatement_each_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseForStatement_each_noType);
+      });
+      _ut.test('test_parseForStatement_each_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseForStatement_each_type);
+      });
+      _ut.test('test_parseForStatement_each_var', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseForStatement_each_var);
+      });
+      _ut.test('test_parseForStatement_loop_c', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseForStatement_loop_c);
+      });
+      _ut.test('test_parseForStatement_loop_cu', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseForStatement_loop_cu);
+      });
+      _ut.test('test_parseForStatement_loop_ecu', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseForStatement_loop_ecu);
+      });
+      _ut.test('test_parseForStatement_loop_i', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseForStatement_loop_i);
+      });
+      _ut.test('test_parseForStatement_loop_ic', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseForStatement_loop_ic);
+      });
+      _ut.test('test_parseForStatement_loop_icu', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseForStatement_loop_icu);
+      });
+      _ut.test('test_parseForStatement_loop_iicuu', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseForStatement_loop_iicuu);
+      });
+      _ut.test('test_parseForStatement_loop_iu', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseForStatement_loop_iu);
+      });
+      _ut.test('test_parseForStatement_loop_u', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseForStatement_loop_u);
+      });
+      _ut.test('test_parseFormalParameterList_empty', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFormalParameterList_empty);
+      });
+      _ut.test('test_parseFormalParameterList_named_multiple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFormalParameterList_named_multiple);
+      });
+      _ut.test('test_parseFormalParameterList_named_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFormalParameterList_named_single);
+      });
+      _ut.test('test_parseFormalParameterList_normal_multiple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFormalParameterList_normal_multiple);
+      });
+      _ut.test('test_parseFormalParameterList_normal_named', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFormalParameterList_normal_named);
+      });
+      _ut.test('test_parseFormalParameterList_normal_positional', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFormalParameterList_normal_positional);
+      });
+      _ut.test('test_parseFormalParameterList_normal_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFormalParameterList_normal_single);
+      });
+      _ut.test('test_parseFormalParameterList_positional_multiple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFormalParameterList_positional_multiple);
+      });
+      _ut.test('test_parseFormalParameterList_positional_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFormalParameterList_positional_single);
+      });
+      _ut.test('test_parseFormalParameter_final_withType_named', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFormalParameter_final_withType_named);
+      });
+      _ut.test('test_parseFormalParameter_final_withType_normal', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFormalParameter_final_withType_normal);
+      });
+      _ut.test('test_parseFormalParameter_final_withType_positional', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFormalParameter_final_withType_positional);
+      });
+      _ut.test('test_parseFormalParameter_nonFinal_withType_named', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFormalParameter_nonFinal_withType_named);
+      });
+      _ut.test('test_parseFormalParameter_nonFinal_withType_normal', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFormalParameter_nonFinal_withType_normal);
+      });
+      _ut.test('test_parseFormalParameter_nonFinal_withType_positional', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFormalParameter_nonFinal_withType_positional);
+      });
+      _ut.test('test_parseFormalParameter_var', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFormalParameter_var);
+      });
+      _ut.test('test_parseFormalParameter_var_named', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFormalParameter_var_named);
+      });
+      _ut.test('test_parseFormalParameter_var_positional', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFormalParameter_var_positional);
+      });
+      _ut.test('test_parseFunctionBody_block', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFunctionBody_block);
+      });
+      _ut.test('test_parseFunctionBody_empty', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFunctionBody_empty);
+      });
+      _ut.test('test_parseFunctionBody_expression', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFunctionBody_expression);
+      });
+      _ut.test('test_parseFunctionDeclarationStatement', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFunctionDeclarationStatement);
+      });
+      _ut.test('test_parseFunctionDeclaration_function', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFunctionDeclaration_function);
+      });
+      _ut.test('test_parseFunctionDeclaration_function_inStatement', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFunctionDeclaration_function_inStatement);
+      });
+      _ut.test('test_parseFunctionDeclaration_getter', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFunctionDeclaration_getter);
+      });
+      _ut.test('test_parseFunctionDeclaration_setter', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFunctionDeclaration_setter);
+      });
+      _ut.test('test_parseFunctionExpression_body_inExpression', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFunctionExpression_body_inExpression);
+      });
+      _ut.test('test_parseFunctionExpression_minimal', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFunctionExpression_minimal);
+      });
+      _ut.test('test_parseGetter_nonStatic', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseGetter_nonStatic);
+      });
+      _ut.test('test_parseGetter_static', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseGetter_static);
+      });
+      _ut.test('test_parseIdentifierList_multiple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseIdentifierList_multiple);
+      });
+      _ut.test('test_parseIdentifierList_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseIdentifierList_single);
+      });
+      _ut.test('test_parseIfStatement_else_block', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseIfStatement_else_block);
+      });
+      _ut.test('test_parseIfStatement_else_statement', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseIfStatement_else_statement);
+      });
+      _ut.test('test_parseIfStatement_noElse_block', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseIfStatement_noElse_block);
+      });
+      _ut.test('test_parseIfStatement_noElse_statement', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseIfStatement_noElse_statement);
+      });
+      _ut.test('test_parseImplementsClause_multiple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseImplementsClause_multiple);
+      });
+      _ut.test('test_parseImplementsClause_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseImplementsClause_single);
+      });
+      _ut.test('test_parseImportDirective_hide', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseImportDirective_hide);
+      });
+      _ut.test('test_parseImportDirective_noCombinator', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseImportDirective_noCombinator);
+      });
+      _ut.test('test_parseImportDirective_prefix', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseImportDirective_prefix);
+      });
+      _ut.test('test_parseImportDirective_prefix_hide_show', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseImportDirective_prefix_hide_show);
+      });
+      _ut.test('test_parseImportDirective_prefix_show_hide', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseImportDirective_prefix_show_hide);
+      });
+      _ut.test('test_parseImportDirective_show', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseImportDirective_show);
+      });
+      _ut.test('test_parseInitializedIdentifierList_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseInitializedIdentifierList_type);
+      });
+      _ut.test('test_parseInitializedIdentifierList_var', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseInitializedIdentifierList_var);
+      });
+      _ut.test('test_parseInstanceCreationExpression_qualifiedType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseInstanceCreationExpression_qualifiedType);
+      });
+      _ut.test('test_parseInstanceCreationExpression_qualifiedType_named', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseInstanceCreationExpression_qualifiedType_named);
+      });
+      _ut.test('test_parseInstanceCreationExpression_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseInstanceCreationExpression_type);
+      });
+      _ut.test('test_parseInstanceCreationExpression_type_named', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseInstanceCreationExpression_type_named);
+      });
+      _ut.test('test_parseLibraryDirective', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseLibraryDirective);
+      });
+      _ut.test('test_parseLibraryIdentifier_multiple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseLibraryIdentifier_multiple);
+      });
+      _ut.test('test_parseLibraryIdentifier_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseLibraryIdentifier_single);
+      });
+      _ut.test('test_parseListLiteral_empty_oneToken', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseListLiteral_empty_oneToken);
+      });
+      _ut.test('test_parseListLiteral_empty_twoTokens', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseListLiteral_empty_twoTokens);
+      });
+      _ut.test('test_parseListLiteral_multiple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseListLiteral_multiple);
+      });
+      _ut.test('test_parseListLiteral_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseListLiteral_single);
+      });
+      _ut.test('test_parseListOrMapLiteral_list_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseListOrMapLiteral_list_noType);
+      });
+      _ut.test('test_parseListOrMapLiteral_list_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseListOrMapLiteral_list_type);
+      });
+      _ut.test('test_parseListOrMapLiteral_map_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseListOrMapLiteral_map_noType);
+      });
+      _ut.test('test_parseListOrMapLiteral_map_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseListOrMapLiteral_map_type);
+      });
+      _ut.test('test_parseLogicalAndExpression', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseLogicalAndExpression);
+      });
+      _ut.test('test_parseLogicalOrExpression', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseLogicalOrExpression);
+      });
+      _ut.test('test_parseMapLiteralEntry', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseMapLiteralEntry);
+      });
+      _ut.test('test_parseMapLiteral_empty', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseMapLiteral_empty);
+      });
+      _ut.test('test_parseMapLiteral_multiple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseMapLiteral_multiple);
+      });
+      _ut.test('test_parseMapLiteral_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseMapLiteral_single);
+      });
+      _ut.test('test_parseModifiers_abstract', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseModifiers_abstract);
+      });
+      _ut.test('test_parseModifiers_const', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseModifiers_const);
+      });
+      _ut.test('test_parseModifiers_external', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseModifiers_external);
+      });
+      _ut.test('test_parseModifiers_factory', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseModifiers_factory);
+      });
+      _ut.test('test_parseModifiers_final', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseModifiers_final);
+      });
+      _ut.test('test_parseModifiers_static', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseModifiers_static);
+      });
+      _ut.test('test_parseModifiers_var', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseModifiers_var);
+      });
+      _ut.test('test_parseMultiplicativeExpression_normal', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseMultiplicativeExpression_normal);
+      });
+      _ut.test('test_parseMultiplicativeExpression_super', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseMultiplicativeExpression_super);
+      });
+      _ut.test('test_parseNewExpression', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNewExpression);
+      });
+      _ut.test('test_parseNonLabeledStatement_const_list_empty', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNonLabeledStatement_const_list_empty);
+      });
+      _ut.test('test_parseNonLabeledStatement_const_list_nonEmpty', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNonLabeledStatement_const_list_nonEmpty);
+      });
+      _ut.test('test_parseNonLabeledStatement_const_map_empty', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNonLabeledStatement_const_map_empty);
+      });
+      _ut.test('test_parseNonLabeledStatement_const_map_nonEmpty', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNonLabeledStatement_const_map_nonEmpty);
+      });
+      _ut.test('test_parseNonLabeledStatement_const_object', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNonLabeledStatement_const_object);
+      });
+      _ut.test('test_parseNonLabeledStatement_const_object_named_typeParameters', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNonLabeledStatement_const_object_named_typeParameters);
+      });
+      _ut.test('test_parseNonLabeledStatement_constructorInvocation', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNonLabeledStatement_constructorInvocation);
+      });
+      _ut.test('test_parseNonLabeledStatement_false', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNonLabeledStatement_false);
+      });
+      _ut.test('test_parseNonLabeledStatement_functionDeclaration', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNonLabeledStatement_functionDeclaration);
+      });
+      _ut.test('test_parseNonLabeledStatement_functionDeclaration_arguments', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNonLabeledStatement_functionDeclaration_arguments);
+      });
+      _ut.test('test_parseNonLabeledStatement_functionExpressionIndex', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNonLabeledStatement_functionExpressionIndex);
+      });
+      _ut.test('test_parseNonLabeledStatement_functionInvocation', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNonLabeledStatement_functionInvocation);
+      });
+      _ut.test('test_parseNonLabeledStatement_invokeFunctionExpression', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNonLabeledStatement_invokeFunctionExpression);
+      });
+      _ut.test('test_parseNonLabeledStatement_null', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNonLabeledStatement_null);
+      });
+      _ut.test('test_parseNonLabeledStatement_startingWithBuiltInIdentifier', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNonLabeledStatement_startingWithBuiltInIdentifier);
+      });
+      _ut.test('test_parseNonLabeledStatement_true', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNonLabeledStatement_true);
+      });
+      _ut.test('test_parseNonLabeledStatement_typeCast', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNonLabeledStatement_typeCast);
+      });
+      _ut.test('test_parseNormalFormalParameter_field_const_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNormalFormalParameter_field_const_noType);
+      });
+      _ut.test('test_parseNormalFormalParameter_field_const_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNormalFormalParameter_field_const_type);
+      });
+      _ut.test('test_parseNormalFormalParameter_field_final_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNormalFormalParameter_field_final_noType);
+      });
+      _ut.test('test_parseNormalFormalParameter_field_final_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNormalFormalParameter_field_final_type);
+      });
+      _ut.test('test_parseNormalFormalParameter_field_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNormalFormalParameter_field_noType);
+      });
+      _ut.test('test_parseNormalFormalParameter_field_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNormalFormalParameter_field_type);
+      });
+      _ut.test('test_parseNormalFormalParameter_field_var', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNormalFormalParameter_field_var);
+      });
+      _ut.test('test_parseNormalFormalParameter_function_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNormalFormalParameter_function_noType);
+      });
+      _ut.test('test_parseNormalFormalParameter_function_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNormalFormalParameter_function_type);
+      });
+      _ut.test('test_parseNormalFormalParameter_function_void', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNormalFormalParameter_function_void);
+      });
+      _ut.test('test_parseNormalFormalParameter_simple_const_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNormalFormalParameter_simple_const_noType);
+      });
+      _ut.test('test_parseNormalFormalParameter_simple_const_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNormalFormalParameter_simple_const_type);
+      });
+      _ut.test('test_parseNormalFormalParameter_simple_final_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNormalFormalParameter_simple_final_noType);
+      });
+      _ut.test('test_parseNormalFormalParameter_simple_final_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNormalFormalParameter_simple_final_type);
+      });
+      _ut.test('test_parseNormalFormalParameter_simple_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNormalFormalParameter_simple_noType);
+      });
+      _ut.test('test_parseNormalFormalParameter_simple_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseNormalFormalParameter_simple_type);
+      });
+      _ut.test('test_parseOperator', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseOperator);
+      });
+      _ut.test('test_parseOptionalReturnType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseOptionalReturnType);
+      });
+      _ut.test('test_parsePartDirective_part', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePartDirective_part);
+      });
+      _ut.test('test_parsePartDirective_partOf', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePartDirective_partOf);
+      });
+      _ut.test('test_parsePostfixExpression_decrement', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePostfixExpression_decrement);
+      });
+      _ut.test('test_parsePostfixExpression_increment', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePostfixExpression_increment);
+      });
+      _ut.test('test_parsePostfixExpression_none_indexExpression', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePostfixExpression_none_indexExpression);
+      });
+      _ut.test('test_parsePostfixExpression_none_methodInvocation', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePostfixExpression_none_methodInvocation);
+      });
+      _ut.test('test_parsePostfixExpression_none_propertyAccess', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePostfixExpression_none_propertyAccess);
+      });
+      _ut.test('test_parsePrefixedIdentifier_noPrefix', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrefixedIdentifier_noPrefix);
+      });
+      _ut.test('test_parsePrefixedIdentifier_prefix', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrefixedIdentifier_prefix);
+      });
+      _ut.test('test_parsePrimaryExpression_argumentDefinitionTest', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_argumentDefinitionTest);
+      });
+      _ut.test('test_parsePrimaryExpression_const', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_const);
+      });
+      _ut.test('test_parsePrimaryExpression_double', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_double);
+      });
+      _ut.test('test_parsePrimaryExpression_false', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_false);
+      });
+      _ut.test('test_parsePrimaryExpression_function_arguments', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_function_arguments);
+      });
+      _ut.test('test_parsePrimaryExpression_function_noArguments', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_function_noArguments);
+      });
+      _ut.test('test_parsePrimaryExpression_hex', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_hex);
+      });
+      _ut.test('test_parsePrimaryExpression_identifier', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_identifier);
+      });
+      _ut.test('test_parsePrimaryExpression_int', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_int);
+      });
+      _ut.test('test_parsePrimaryExpression_listLiteral', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_listLiteral);
+      });
+      _ut.test('test_parsePrimaryExpression_listLiteral_index', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_listLiteral_index);
+      });
+      _ut.test('test_parsePrimaryExpression_listLiteral_typed', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_listLiteral_typed);
+      });
+      _ut.test('test_parsePrimaryExpression_mapLiteral', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_mapLiteral);
+      });
+      _ut.test('test_parsePrimaryExpression_mapLiteral_typed', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_mapLiteral_typed);
+      });
+      _ut.test('test_parsePrimaryExpression_new', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_new);
+      });
+      _ut.test('test_parsePrimaryExpression_null', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_null);
+      });
+      _ut.test('test_parsePrimaryExpression_parenthesized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_parenthesized);
+      });
+      _ut.test('test_parsePrimaryExpression_string', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_string);
+      });
+      _ut.test('test_parsePrimaryExpression_super', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_super);
+      });
+      _ut.test('test_parsePrimaryExpression_this', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_this);
+      });
+      _ut.test('test_parsePrimaryExpression_true', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parsePrimaryExpression_true);
+      });
+      _ut.test('test_parseRedirectingConstructorInvocation_named', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseRedirectingConstructorInvocation_named);
+      });
+      _ut.test('test_parseRedirectingConstructorInvocation_unnamed', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseRedirectingConstructorInvocation_unnamed);
+      });
+      _ut.test('test_parseRelationalExpression_as', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseRelationalExpression_as);
+      });
+      _ut.test('test_parseRelationalExpression_is', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseRelationalExpression_is);
+      });
+      _ut.test('test_parseRelationalExpression_isNot', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseRelationalExpression_isNot);
+      });
+      _ut.test('test_parseRelationalExpression_normal', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseRelationalExpression_normal);
+      });
+      _ut.test('test_parseRelationalExpression_super', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseRelationalExpression_super);
+      });
+      _ut.test('test_parseReturnStatement_noValue', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseReturnStatement_noValue);
+      });
+      _ut.test('test_parseReturnStatement_value', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseReturnStatement_value);
+      });
+      _ut.test('test_parseReturnType_nonVoid', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseReturnType_nonVoid);
+      });
+      _ut.test('test_parseReturnType_void', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseReturnType_void);
+      });
+      _ut.test('test_parseSetter_nonStatic', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseSetter_nonStatic);
+      });
+      _ut.test('test_parseSetter_static', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseSetter_static);
+      });
+      _ut.test('test_parseShiftExpression_normal', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseShiftExpression_normal);
+      });
+      _ut.test('test_parseShiftExpression_super', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseShiftExpression_super);
+      });
+      _ut.test('test_parseSimpleIdentifier1_normalIdentifier', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseSimpleIdentifier1_normalIdentifier);
+      });
+      _ut.test('test_parseSimpleIdentifier_builtInIdentifier', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseSimpleIdentifier_builtInIdentifier);
+      });
+      _ut.test('test_parseSimpleIdentifier_normalIdentifier', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseSimpleIdentifier_normalIdentifier);
+      });
+      _ut.test('test_parseStatement_functionDeclaration', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseStatement_functionDeclaration);
+      });
+      _ut.test('test_parseStatement_mulipleLabels', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseStatement_mulipleLabels);
+      });
+      _ut.test('test_parseStatement_noLabels', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseStatement_noLabels);
+      });
+      _ut.test('test_parseStatement_singleLabel', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseStatement_singleLabel);
+      });
+      _ut.test('test_parseStatements_multiple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseStatements_multiple);
+      });
+      _ut.test('test_parseStatements_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseStatements_single);
+      });
+      _ut.test('test_parseStringLiteral_adjacent', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseStringLiteral_adjacent);
+      });
+      _ut.test('test_parseStringLiteral_interpolated', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseStringLiteral_interpolated);
+      });
+      _ut.test('test_parseStringLiteral_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseStringLiteral_single);
+      });
+      _ut.test('test_parseSuperConstructorInvocation_named', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseSuperConstructorInvocation_named);
+      });
+      _ut.test('test_parseSuperConstructorInvocation_unnamed', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseSuperConstructorInvocation_unnamed);
+      });
+      _ut.test('test_parseSwitchStatement_case', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseSwitchStatement_case);
+      });
+      _ut.test('test_parseSwitchStatement_empty', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseSwitchStatement_empty);
+      });
+      _ut.test('test_parseSwitchStatement_labeledCase', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseSwitchStatement_labeledCase);
+      });
+      _ut.test('test_parseSwitchStatement_labeledStatementInCase', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseSwitchStatement_labeledStatementInCase);
+      });
+      _ut.test('test_parseThrowExpressionWithoutCascade_expression', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseThrowExpressionWithoutCascade_expression);
+      });
+      _ut.test('test_parseThrowExpressionWithoutCascade_noExpression', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseThrowExpressionWithoutCascade_noExpression);
+      });
+      _ut.test('test_parseThrowExpression_expression', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseThrowExpression_expression);
+      });
+      _ut.test('test_parseThrowExpression_noExpression', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseThrowExpression_noExpression);
+      });
+      _ut.test('test_parseTryStatement_catch', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTryStatement_catch);
+      });
+      _ut.test('test_parseTryStatement_catch_finally', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTryStatement_catch_finally);
+      });
+      _ut.test('test_parseTryStatement_finally', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTryStatement_finally);
+      });
+      _ut.test('test_parseTryStatement_multiple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTryStatement_multiple);
+      });
+      _ut.test('test_parseTryStatement_on', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTryStatement_on);
+      });
+      _ut.test('test_parseTryStatement_on_catch', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTryStatement_on_catch);
+      });
+      _ut.test('test_parseTryStatement_on_catch_finally', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTryStatement_on_catch_finally);
+      });
+      _ut.test('test_parseTypeAlias_noParameters', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTypeAlias_noParameters);
+      });
+      _ut.test('test_parseTypeAlias_noReturnType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTypeAlias_noReturnType);
+      });
+      _ut.test('test_parseTypeAlias_parameterizedReturnType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTypeAlias_parameterizedReturnType);
+      });
+      _ut.test('test_parseTypeAlias_parameters', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTypeAlias_parameters);
+      });
+      _ut.test('test_parseTypeAlias_typeParameters', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTypeAlias_typeParameters);
+      });
+      _ut.test('test_parseTypeAlias_voidReturnType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTypeAlias_voidReturnType);
+      });
+      _ut.test('test_parseTypeArgumentList_multiple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTypeArgumentList_multiple);
+      });
+      _ut.test('test_parseTypeArgumentList_nested', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTypeArgumentList_nested);
+      });
+      _ut.test('test_parseTypeArgumentList_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTypeArgumentList_single);
+      });
+      _ut.test('test_parseTypeName_parameterized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTypeName_parameterized);
+      });
+      _ut.test('test_parseTypeName_simple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTypeName_simple);
+      });
+      _ut.test('test_parseTypeParameterList_multiple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTypeParameterList_multiple);
+      });
+      _ut.test('test_parseTypeParameterList_parameterizedWithTrailingEquals', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTypeParameterList_parameterizedWithTrailingEquals);
+      });
+      _ut.test('test_parseTypeParameterList_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTypeParameterList_single);
+      });
+      _ut.test('test_parseTypeParameterList_withTrailingEquals', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTypeParameterList_withTrailingEquals);
+      });
+      _ut.test('test_parseTypeParameter_bounded', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTypeParameter_bounded);
+      });
+      _ut.test('test_parseTypeParameter_simple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseTypeParameter_simple);
+      });
+      _ut.test('test_parseUnaryExpression_decrement_normal', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseUnaryExpression_decrement_normal);
+      });
+      _ut.test('test_parseUnaryExpression_decrement_super', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseUnaryExpression_decrement_super);
+      });
+      _ut.test('test_parseUnaryExpression_increment_normal', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseUnaryExpression_increment_normal);
+      });
+      _ut.test('test_parseUnaryExpression_minus_normal', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseUnaryExpression_minus_normal);
+      });
+      _ut.test('test_parseUnaryExpression_minus_super', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseUnaryExpression_minus_super);
+      });
+      _ut.test('test_parseUnaryExpression_not_normal', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseUnaryExpression_not_normal);
+      });
+      _ut.test('test_parseUnaryExpression_not_super', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseUnaryExpression_not_super);
+      });
+      _ut.test('test_parseUnaryExpression_tilda_normal', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseUnaryExpression_tilda_normal);
+      });
+      _ut.test('test_parseUnaryExpression_tilda_super', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseUnaryExpression_tilda_super);
+      });
+      _ut.test('test_parseVariableDeclarationList2_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseVariableDeclarationList2_type);
+      });
+      _ut.test('test_parseVariableDeclarationList2_var', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseVariableDeclarationList2_var);
+      });
+      _ut.test('test_parseVariableDeclarationList_const_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseVariableDeclarationList_const_noType);
+      });
+      _ut.test('test_parseVariableDeclarationList_const_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseVariableDeclarationList_const_type);
+      });
+      _ut.test('test_parseVariableDeclarationList_final_noType', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseVariableDeclarationList_final_noType);
+      });
+      _ut.test('test_parseVariableDeclarationList_final_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseVariableDeclarationList_final_type);
+      });
+      _ut.test('test_parseVariableDeclarationList_type_multiple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseVariableDeclarationList_type_multiple);
+      });
+      _ut.test('test_parseVariableDeclarationList_type_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseVariableDeclarationList_type_single);
+      });
+      _ut.test('test_parseVariableDeclarationList_var_multiple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseVariableDeclarationList_var_multiple);
+      });
+      _ut.test('test_parseVariableDeclarationList_var_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseVariableDeclarationList_var_single);
+      });
+      _ut.test('test_parseVariableDeclarationStatement_multiple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseVariableDeclarationStatement_multiple);
+      });
+      _ut.test('test_parseVariableDeclarationStatement_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseVariableDeclarationStatement_single);
+      });
+      _ut.test('test_parseVariableDeclaration_equals', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseVariableDeclaration_equals);
+      });
+      _ut.test('test_parseVariableDeclaration_noEquals', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseVariableDeclaration_noEquals);
+      });
+      _ut.test('test_parseWhileStatement', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseWhileStatement);
+      });
+      _ut.test('test_parseWithClause_multiple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseWithClause_multiple);
+      });
+      _ut.test('test_parseWithClause_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseWithClause_single);
+      });
+      _ut.test('test_skipPrefixedIdentifier_invalid', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_skipPrefixedIdentifier_invalid);
+      });
+      _ut.test('test_skipPrefixedIdentifier_notPrefixed', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_skipPrefixedIdentifier_notPrefixed);
+      });
+      _ut.test('test_skipPrefixedIdentifier_prefixed', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_skipPrefixedIdentifier_prefixed);
+      });
+      _ut.test('test_skipReturnType_invalid', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_skipReturnType_invalid);
+      });
+      _ut.test('test_skipReturnType_type', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_skipReturnType_type);
+      });
+      _ut.test('test_skipReturnType_void', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_skipReturnType_void);
+      });
+      _ut.test('test_skipSimpleIdentifier_identifier', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_skipSimpleIdentifier_identifier);
+      });
+      _ut.test('test_skipSimpleIdentifier_invalid', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_skipSimpleIdentifier_invalid);
+      });
+      _ut.test('test_skipSimpleIdentifier_pseudoKeyword', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_skipSimpleIdentifier_pseudoKeyword);
+      });
+      _ut.test('test_skipStringLiteral_adjacent', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_skipStringLiteral_adjacent);
+      });
+      _ut.test('test_skipStringLiteral_interpolated', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_skipStringLiteral_interpolated);
+      });
+      _ut.test('test_skipStringLiteral_invalid', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_skipStringLiteral_invalid);
+      });
+      _ut.test('test_skipStringLiteral_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_skipStringLiteral_single);
+      });
+      _ut.test('test_skipTypeArgumentList_invalid', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_skipTypeArgumentList_invalid);
+      });
+      _ut.test('test_skipTypeArgumentList_multiple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_skipTypeArgumentList_multiple);
+      });
+      _ut.test('test_skipTypeArgumentList_single', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_skipTypeArgumentList_single);
+      });
+      _ut.test('test_skipTypeName_invalid', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_skipTypeName_invalid);
+      });
+      _ut.test('test_skipTypeName_parameterized', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_skipTypeName_parameterized);
+      });
+      _ut.test('test_skipTypeName_simple', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_skipTypeName_simple);
+      });
+    });
+  }
+}
+class AnalysisErrorListener_4 implements AnalysisErrorListener {
+  void onError(AnalysisError event) {
+    JUnitTestCase.fail("Unexpected compilation error: ${event.message} (${event.offset}, ${event.length})");
+  }
+}
+/**
+ * The class {@code ComplexParserTest} defines parser tests that test the parsing of more complex
+ * code fragments or the interactions between multiple parsing methods. For example, tests to ensure
+ * that the precedence of operations is being handled correctly should be defined in this class.
+ * <p>
+ * Simpler tests should be defined in the class {@link SimpleParserTest}.
+ */
+class ComplexParserTest extends ParserTestCase {
+  void test_additiveExpression_normal() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x + y - z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_additiveExpression_noSpaces() {
+    BinaryExpression expression = ParserTestCase.parseExpression("i+1", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftOperand);
+    EngineTestCase.assertInstanceOf(IntegerLiteral, expression.rightOperand);
+  }
+  void test_additiveExpression_precedence_multiplicative_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x * y + z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_additiveExpression_precedence_multiplicative_left_withSuper() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super * y - z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_additiveExpression_precedence_multiplicative_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x + y * z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_additiveExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super + y - z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_assignableExpression_arguments_normal_chain() {
+    PropertyAccess propertyAccess1 = ParserTestCase.parseExpression("a(b)(c).d(e).f", []);
+    JUnitTestCase.assertEquals("f", propertyAccess1.propertyName.name);
+    MethodInvocation invocation2 = EngineTestCase.assertInstanceOf(MethodInvocation, propertyAccess1.target);
+    JUnitTestCase.assertEquals("d", invocation2.methodName.name);
+    ArgumentList argumentList2 = invocation2.argumentList;
+    JUnitTestCase.assertNotNull(argumentList2);
+    EngineTestCase.assertSize(1, argumentList2.arguments);
+    FunctionExpressionInvocation invocation3 = EngineTestCase.assertInstanceOf(FunctionExpressionInvocation, invocation2.target);
+    ArgumentList argumentList3 = invocation3.argumentList;
+    JUnitTestCase.assertNotNull(argumentList3);
+    EngineTestCase.assertSize(1, argumentList3.arguments);
+    MethodInvocation invocation4 = EngineTestCase.assertInstanceOf(MethodInvocation, invocation3.function);
+    JUnitTestCase.assertEquals("a", invocation4.methodName.name);
+    ArgumentList argumentList4 = invocation4.argumentList;
+    JUnitTestCase.assertNotNull(argumentList4);
+    EngineTestCase.assertSize(1, argumentList4.arguments);
+  }
+  void test_assignmentExpression_compound() {
+    AssignmentExpression expression = ParserTestCase.parseExpression("x = y = 0", []);
+    EngineTestCase.assertInstanceOf(SimpleIdentifier, expression.leftHandSide);
+    EngineTestCase.assertInstanceOf(AssignmentExpression, expression.rightHandSide);
+  }
+  void test_assignmentExpression_indexExpression() {
+    AssignmentExpression expression = ParserTestCase.parseExpression("x[1] = 0", []);
+    EngineTestCase.assertInstanceOf(IndexExpression, expression.leftHandSide);
+    EngineTestCase.assertInstanceOf(IntegerLiteral, expression.rightHandSide);
+  }
+  void test_assignmentExpression_prefixedIdentifier() {
+    AssignmentExpression expression = ParserTestCase.parseExpression("x.y = 0", []);
+    EngineTestCase.assertInstanceOf(PrefixedIdentifier, expression.leftHandSide);
+    EngineTestCase.assertInstanceOf(IntegerLiteral, expression.rightHandSide);
+  }
+  void test_assignmentExpression_propertyAccess() {
+    AssignmentExpression expression = ParserTestCase.parseExpression("super.y = 0", []);
+    EngineTestCase.assertInstanceOf(PropertyAccess, expression.leftHandSide);
+    EngineTestCase.assertInstanceOf(IntegerLiteral, expression.rightHandSide);
+  }
+  void test_bitwiseAndExpression_normal() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x & y & z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_bitwiseAndExpression_precedence_equality_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x == y & z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_bitwiseAndExpression_precedence_equality_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x & y == z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_bitwiseAndExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super & y & z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_bitwiseOrExpression_normal() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x | y | z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_bitwiseOrExpression_precedence_xor_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x ^ y | z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_bitwiseOrExpression_precedence_xor_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x | y ^ z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_bitwiseOrExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super | y | z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_bitwiseXorExpression_normal() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x ^ y ^ z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_bitwiseXorExpression_precedence_and_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x & y ^ z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_bitwiseXorExpression_precedence_and_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x ^ y & z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_bitwiseXorExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super ^ y ^ z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  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(PrefixExpression, conditional.thenExpression);
+    EngineTestCase.assertInstanceOf(ArgumentDefinitionTest, (conditional.thenExpression as PrefixExpression).operand);
+    EngineTestCase.assertInstanceOf(PrefixExpression, conditional.elseExpression);
+    EngineTestCase.assertInstanceOf(ArgumentDefinitionTest, (conditional.elseExpression as PrefixExpression).operand);
+  }
+  void test_conditionalExpression_precedence_logicalOrExpression() {
+    ConditionalExpression expression = ParserTestCase.parseExpression("a | b ? y : z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.condition);
+  }
+  void test_constructor_initializer_withParenthesizedExpression() {
+    CompilationUnit unit = ParserTestCase.parseCompilationUnit(EngineTestCase.createSource(["class C {", "  C() :", "    this.a = (b == null ? c : d) {", "  }", "}"]), []);
+    NodeList<CompilationUnitMember> declarations2 = unit.declarations;
+    EngineTestCase.assertSize(1, declarations2);
+  }
+  void test_equalityExpression_normal() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x == y != z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_equalityExpression_precedence_relational_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x is y == z", []);
+    EngineTestCase.assertInstanceOf(IsExpression, expression.leftOperand);
+  }
+  void test_equalityExpression_precedence_relational_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x == y is z", []);
+    EngineTestCase.assertInstanceOf(IsExpression, expression.rightOperand);
+  }
+  void test_equalityExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super == y != z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_logicalAndExpression() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x && y && z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_logicalAndExpression_precedence_bitwiseOr_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x | y && z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_logicalAndExpression_precedence_bitwiseOr_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x && y | z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_logicalOrExpression() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x || y || z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_logicalOrExpression_precedence_logicalAnd_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x && y || z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_logicalOrExpression_precedence_logicalAnd_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x || y && z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_multipleLabels_statement() {
+    LabeledStatement statement = ParserTestCase.parseStatement("a: b: c: return x;", []);
+    EngineTestCase.assertSize(3, statement.labels);
+    EngineTestCase.assertInstanceOf(ReturnStatement, statement.statement);
+  }
+  void test_multiplicativeExpression_normal() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x * y / z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_multiplicativeExpression_precedence_unary_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("-x * y", []);
+    EngineTestCase.assertInstanceOf(PrefixExpression, expression.leftOperand);
+  }
+  void test_multiplicativeExpression_precedence_unary_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x * -y", []);
+    EngineTestCase.assertInstanceOf(PrefixExpression, expression.rightOperand);
+  }
+  void test_multiplicativeExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super * y / z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_relationalExpression_precedence_shift_right() {
+    IsExpression expression = ParserTestCase.parseExpression("x << y is z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.expression);
+  }
+  void test_shiftExpression_normal() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x >> 4 << 3", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_shiftExpression_precedence_additive_left() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x + y << z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  void test_shiftExpression_precedence_additive_right() {
+    BinaryExpression expression = ParserTestCase.parseExpression("x << y + z", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.rightOperand);
+  }
+  void test_shiftExpression_super() {
+    BinaryExpression expression = ParserTestCase.parseExpression("super >> 4 << 3", []);
+    EngineTestCase.assertInstanceOf(BinaryExpression, expression.leftOperand);
+  }
+  static dartSuite() {
+    _ut.group('ComplexParserTest', () {
+      _ut.test('test_additiveExpression_noSpaces', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_additiveExpression_noSpaces);
+      });
+      _ut.test('test_additiveExpression_normal', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_additiveExpression_normal);
+      });
+      _ut.test('test_additiveExpression_precedence_multiplicative_left', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_additiveExpression_precedence_multiplicative_left);
+      });
+      _ut.test('test_additiveExpression_precedence_multiplicative_left_withSuper', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_additiveExpression_precedence_multiplicative_left_withSuper);
+      });
+      _ut.test('test_additiveExpression_precedence_multiplicative_right', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_additiveExpression_precedence_multiplicative_right);
+      });
+      _ut.test('test_additiveExpression_super', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_additiveExpression_super);
+      });
+      _ut.test('test_assignableExpression_arguments_normal_chain', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_assignableExpression_arguments_normal_chain);
+      });
+      _ut.test('test_assignmentExpression_compound', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_assignmentExpression_compound);
+      });
+      _ut.test('test_assignmentExpression_indexExpression', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_assignmentExpression_indexExpression);
+      });
+      _ut.test('test_assignmentExpression_prefixedIdentifier', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_assignmentExpression_prefixedIdentifier);
+      });
+      _ut.test('test_assignmentExpression_propertyAccess', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_assignmentExpression_propertyAccess);
+      });
+      _ut.test('test_bitwiseAndExpression_normal', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_bitwiseAndExpression_normal);
+      });
+      _ut.test('test_bitwiseAndExpression_precedence_equality_left', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_bitwiseAndExpression_precedence_equality_left);
+      });
+      _ut.test('test_bitwiseAndExpression_precedence_equality_right', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_bitwiseAndExpression_precedence_equality_right);
+      });
+      _ut.test('test_bitwiseAndExpression_super', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_bitwiseAndExpression_super);
+      });
+      _ut.test('test_bitwiseOrExpression_normal', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_bitwiseOrExpression_normal);
+      });
+      _ut.test('test_bitwiseOrExpression_precedence_xor_left', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_bitwiseOrExpression_precedence_xor_left);
+      });
+      _ut.test('test_bitwiseOrExpression_precedence_xor_right', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_bitwiseOrExpression_precedence_xor_right);
+      });
+      _ut.test('test_bitwiseOrExpression_super', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_bitwiseOrExpression_super);
+      });
+      _ut.test('test_bitwiseXorExpression_normal', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_bitwiseXorExpression_normal);
+      });
+      _ut.test('test_bitwiseXorExpression_precedence_and_left', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_bitwiseXorExpression_precedence_and_left);
+      });
+      _ut.test('test_bitwiseXorExpression_precedence_and_right', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_bitwiseXorExpression_precedence_and_right);
+      });
+      _ut.test('test_bitwiseXorExpression_super', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_bitwiseXorExpression_super);
+      });
+      _ut.test('test_conditionalExpression_precedence_argumentDefinitionTest_not', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_conditionalExpression_precedence_argumentDefinitionTest_not);
+      });
+      _ut.test('test_conditionalExpression_precedence_logicalOrExpression', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_conditionalExpression_precedence_logicalOrExpression);
+      });
+      _ut.test('test_constructor_initializer_withParenthesizedExpression', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_constructor_initializer_withParenthesizedExpression);
+      });
+      _ut.test('test_equalityExpression_normal', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_equalityExpression_normal);
+      });
+      _ut.test('test_equalityExpression_precedence_relational_left', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_equalityExpression_precedence_relational_left);
+      });
+      _ut.test('test_equalityExpression_precedence_relational_right', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_equalityExpression_precedence_relational_right);
+      });
+      _ut.test('test_equalityExpression_super', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_equalityExpression_super);
+      });
+      _ut.test('test_logicalAndExpression', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_logicalAndExpression);
+      });
+      _ut.test('test_logicalAndExpression_precedence_bitwiseOr_left', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_logicalAndExpression_precedence_bitwiseOr_left);
+      });
+      _ut.test('test_logicalAndExpression_precedence_bitwiseOr_right', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_logicalAndExpression_precedence_bitwiseOr_right);
+      });
+      _ut.test('test_logicalOrExpression', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_logicalOrExpression);
+      });
+      _ut.test('test_logicalOrExpression_precedence_logicalAnd_left', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_logicalOrExpression_precedence_logicalAnd_left);
+      });
+      _ut.test('test_logicalOrExpression_precedence_logicalAnd_right', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_logicalOrExpression_precedence_logicalAnd_right);
+      });
+      _ut.test('test_multipleLabels_statement', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_multipleLabels_statement);
+      });
+      _ut.test('test_multiplicativeExpression_normal', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_multiplicativeExpression_normal);
+      });
+      _ut.test('test_multiplicativeExpression_precedence_unary_left', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_multiplicativeExpression_precedence_unary_left);
+      });
+      _ut.test('test_multiplicativeExpression_precedence_unary_right', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_multiplicativeExpression_precedence_unary_right);
+      });
+      _ut.test('test_multiplicativeExpression_super', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_multiplicativeExpression_super);
+      });
+      _ut.test('test_relationalExpression_precedence_shift_right', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_relationalExpression_precedence_shift_right);
+      });
+      _ut.test('test_shiftExpression_normal', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_shiftExpression_normal);
+      });
+      _ut.test('test_shiftExpression_precedence_additive_left', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_shiftExpression_precedence_additive_left);
+      });
+      _ut.test('test_shiftExpression_precedence_additive_right', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_shiftExpression_precedence_additive_right);
+      });
+      _ut.test('test_shiftExpression_super', () {
+        final __test = new ComplexParserTest();
+        runJUnitTest(__test, __test.test_shiftExpression_super);
+      });
+    });
+  }
+}
+/**
+ * The class {@code ErrorParserTest} defines parser tests that test the parsing of code to ensure
+ * that errors are correctly reported, and in some cases, not reported.
+ */
+class ErrorParserTest extends ParserTestCase {
+  void fail_expectedListOrMapLiteral() {
+    TypedLiteral literal = ParserTestCase.parse3("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]);
+  }
+  void fail_invalidCommentReference__new_nonIdentifier() {
+    ParserTestCase.parse3("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]);
+  }
+  void fail_invalidCommentReference__nonNew_nonIdentifier() {
+    ParserTestCase.parse3("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]);
+  }
+  void fail_missingFunctionParameters_local_nonVoid_block() {
+    ParserTestCase.parse4("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]);
+  }
+  void fail_unexpectedToken_invalidPostfixExpression() {
+    ParserTestCase.parse4("parseExpression", "f()++", [ParserErrorCode.UNEXPECTED_TOKEN]);
+  }
+  void fail_voidVariable_initializer() {
+    ParserTestCase.parse4("parseStatement", "void x = 0;", [ParserErrorCode.VOID_VARIABLE]);
+  }
+  void fail_voidVariable_noInitializer() {
+    ParserTestCase.parse4("parseStatement", "void x;", [ParserErrorCode.VOID_VARIABLE]);
+  }
+  void test_abstractClassMember_constructor() {
+    ParserTestCase.parse3("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]);
+  }
+  void test_abstractClassMember_getter() {
+    ParserTestCase.parse3("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]);
+  }
+  void test_abstractClassMember_setter() {
+    ParserTestCase.parse3("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]);
+  }
+  void test_abstractTopLevelFunction_getter() {
+    ParserTestCase.parse4("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]);
+  }
+  void test_abstractTopLevelVariable() {
+    ParserTestCase.parse4("parseCompilationUnit", "abstract C f;", [ParserErrorCode.ABSTRACT_TOP_LEVEL_VARIABLE]);
+  }
+  void test_abstractTypeDef() {
+    ParserTestCase.parse4("parseCompilationUnit", "abstract typedef F();", [ParserErrorCode.ABSTRACT_TYPEDEF]);
+  }
+  void test_breakOutsideOfLoop_breakInDoStatement() {
+    ParserTestCase.parse4("parseDoStatement", "do {break;} while (x);", []);
+  }
+  void test_breakOutsideOfLoop_breakInForStatement() {
+    ParserTestCase.parse4("parseForStatement", "for (; x;) {break;}", []);
+  }
+  void test_breakOutsideOfLoop_breakInIfStatement() {
+    ParserTestCase.parse4("parseIfStatement", "if (x) {break;}", [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]);
+  }
+  void test_breakOutsideOfLoop_breakInSwitchStatement() {
+    ParserTestCase.parse4("parseSwitchStatement", "switch (x) {case 1: break;}", []);
+  }
+  void test_breakOutsideOfLoop_breakInWhileStatement() {
+    ParserTestCase.parse4("parseWhileStatement", "while (x) {break;}", []);
+  }
+  void test_breakOutsideOfLoop_functionExpression_inALoop() {
+    ParserTestCase.parse4("parseStatement", "for(; x;) {() {break;};}", [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]);
+  }
+  void test_breakOutsideOfLoop_functionExpression_withALoop() {
+    ParserTestCase.parse4("parseStatement", "() {for (; x;) {break;}};", []);
+  }
+  void test_builtInIdentifierAsTypeDefName() {
+    ParserTestCase.parse3("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]);
+  }
+  void test_builtInIdentifierAsTypeVariableName() {
+    ParserTestCase.parse4("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]);
+  }
+  void test_constAndVar() {
+    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "const var x;", [ParserErrorCode.CONST_AND_VAR]);
+  }
+  void test_constClass() {
+    ParserTestCase.parse4("parseCompilationUnit", "const class C {}", [ParserErrorCode.CONST_CLASS]);
+  }
+  void test_constMethod() {
+    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "const int m() {}", [ParserErrorCode.CONST_METHOD]);
+  }
+  void test_constTypedef() {
+    ParserTestCase.parse4("parseCompilationUnit", "const typedef F();", [ParserErrorCode.CONST_TYPEDEF]);
+  }
+  void test_continueOutsideOfLoop_continueInDoStatement() {
+    ParserTestCase.parse4("parseDoStatement", "do {continue;} while (x);", []);
+  }
+  void test_continueOutsideOfLoop_continueInForStatement() {
+    ParserTestCase.parse4("parseForStatement", "for (; x;) {continue;}", []);
+  }
+  void test_continueOutsideOfLoop_continueInIfStatement() {
+    ParserTestCase.parse4("parseIfStatement", "if (x) {continue;}", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
+  }
+  void test_continueOutsideOfLoop_continueInSwitchStatement() {
+    ParserTestCase.parse4("parseSwitchStatement", "switch (x) {case 1: continue a;}", []);
+  }
+  void test_continueOutsideOfLoop_continueInWhileStatement() {
+    ParserTestCase.parse4("parseWhileStatement", "while (x) {continue;}", []);
+  }
+  void test_continueOutsideOfLoop_functionExpression_inALoop() {
+    ParserTestCase.parse4("parseStatement", "for(; x;) {() {continue;};}", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
+  }
+  void test_continueOutsideOfLoop_functionExpression_withALoop() {
+    ParserTestCase.parse4("parseStatement", "() {for (; x;) {continue;}};", []);
+  }
+  void test_continueWithoutLabelInCase_error() {
+    ParserTestCase.parse4("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;}", []);
+  }
+  void test_continueWithoutLabelInCase_noError_switchInLoop() {
+    ParserTestCase.parse4("parseWhileStatement", "while (a) { switch (b) {default: continue;}}", []);
+  }
+  void test_directiveAfterDeclaration_classBeforeDirective() {
+    CompilationUnit unit = ParserTestCase.parse4("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]);
+    JUnitTestCase.assertNotNull(unit);
+  }
+  void test_duplicatedModifier_const() {
+    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "const const m;", [ParserErrorCode.DUPLICATED_MODIFIER]);
+  }
+  void test_duplicatedModifier_external() {
+    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "external external f();", [ParserErrorCode.DUPLICATED_MODIFIER]);
+  }
+  void test_duplicatedModifier_factory() {
+    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "factory factory C() {}", [ParserErrorCode.DUPLICATED_MODIFIER]);
+  }
+  void test_duplicatedModifier_final() {
+    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "final final m;", [ParserErrorCode.DUPLICATED_MODIFIER]);
+  }
+  void test_duplicatedModifier_static() {
+    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "static static m;", [ParserErrorCode.DUPLICATED_MODIFIER]);
+  }
+  void test_duplicatedModifier_var() {
+    ParserTestCase.parse3("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]);
+  }
+  void test_expectedCaseOrDefault() {
+    ParserTestCase.parse4("parseSwitchStatement", "switch (e) {break;}", [ParserErrorCode.EXPECTED_CASE_OR_DEFAULT]);
+  }
+  void test_expectedStringLiteral() {
+    StringLiteral expression = ParserTestCase.parse4("parseStringLiteral", "1", [ParserErrorCode.EXPECTED_STRING_LITERAL]);
+    JUnitTestCase.assertTrue(expression.isSynthetic());
+  }
+  void test_expectedToken_commaMissingInArgumentList() {
+    ParserTestCase.parse4("parseArgumentList", "(x, y z)", [ParserErrorCode.EXPECTED_TOKEN]);
+  }
+  void test_expectedToken_semicolonMissingAfterExpression() {
+    ParserTestCase.parse4("parseStatement", "x", [ParserErrorCode.EXPECTED_TOKEN]);
+  }
+  void test_expectedToken_whileMissingInDoStatement() {
+    ParserTestCase.parse4("parseStatement", "do {} (x);", [ParserErrorCode.EXPECTED_TOKEN]);
+  }
+  void test_exportDirectiveAfterPartDirective() {
+    ParserTestCase.parse4("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]);
+  }
+  void test_externalAfterFactory() {
+    ParserTestCase.parse3("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]);
+  }
+  void test_externalClass() {
+    ParserTestCase.parse4("parseCompilationUnit", "external class C {}", [ParserErrorCode.EXTERNAL_CLASS]);
+  }
+  void test_externalConstructorWithBody_factory() {
+    ParserTestCase.parse3("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]);
+  }
+  void test_externalField_const() {
+    ParserTestCase.parse3("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]);
+  }
+  void test_externalField_static() {
+    ParserTestCase.parse3("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]);
+  }
+  void test_externalField_untyped() {
+    ParserTestCase.parse3("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]);
+  }
+  void test_externalMethodWithBody() {
+    ParserTestCase.parse3("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]);
+  }
+  void test_externalSetterWithBody() {
+    ParserTestCase.parse3("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]);
+  }
+  void test_factoryTopLevelDeclaration_class() {
+    ParserTestCase.parse4("parseCompilationUnit", "factory class C {}", [ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION]);
+  }
+  void test_factoryTopLevelDeclaration_typedef() {
+    ParserTestCase.parse4("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]);
+  }
+  void test_finalAndVar() {
+    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "final var x;", [ParserErrorCode.FINAL_AND_VAR]);
+  }
+  void test_finalClass() {
+    ParserTestCase.parse4("parseCompilationUnit", "final class C {}", [ParserErrorCode.FINAL_CLASS]);
+  }
+  void test_finalConstructor() {
+    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "final C() {}", [ParserErrorCode.FINAL_CONSTRUCTOR]);
+  }
+  void test_finalMethod() {
+    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "final int m() {}", [ParserErrorCode.FINAL_METHOD]);
+  }
+  void test_finalTypedef() {
+    ParserTestCase.parse4("parseCompilationUnit", "final typedef F();", [ParserErrorCode.FINAL_TYPEDEF]);
+  }
+  void test_getterWithParameters() {
+    ParserTestCase.parse3("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]);
+  }
+  void test_implementsBeforeExtends() {
+    ParserTestCase.parse4("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]);
+  }
+  void test_importDirectiveAfterPartDirective() {
+    ParserTestCase.parse4("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]);
+  }
+  void test_invalidCodePoint() {
+    ParserTestCase.parse4("parseStringLiteral", "'\\uD900'", [ParserErrorCode.INVALID_CODE_POINT]);
+  }
+  void test_invalidHexEscape_invalidDigit() {
+    ParserTestCase.parse4("parseStringLiteral", "'\\x0 a'", [ParserErrorCode.INVALID_HEX_ESCAPE]);
+  }
+  void test_invalidHexEscape_tooFewDigits() {
+    ParserTestCase.parse4("parseStringLiteral", "'\\x0'", [ParserErrorCode.INVALID_HEX_ESCAPE]);
+  }
+  void test_invalidOperatorForSuper() {
+    ParserTestCase.parse4("parseUnaryExpression", "++super", [ParserErrorCode.INVALID_OPERATOR_FOR_SUPER]);
+  }
+  void test_invalidUnicodeEscape_incomplete_noDigits() {
+    ParserTestCase.parse4("parseStringLiteral", "'\\u{'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
+  }
+  void test_invalidUnicodeEscape_incomplete_someDigits() {
+    ParserTestCase.parse4("parseStringLiteral", "'\\u{0A'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
+  }
+  void test_invalidUnicodeEscape_invalidDigit() {
+    ParserTestCase.parse4("parseStringLiteral", "'\\u0 a'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
+  }
+  void test_invalidUnicodeEscape_tooFewDigits_fixed() {
+    ParserTestCase.parse4("parseStringLiteral", "'\\u04'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
+  }
+  void test_invalidUnicodeEscape_tooFewDigits_variable() {
+    ParserTestCase.parse4("parseStringLiteral", "'\\u{}'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
+  }
+  void test_invalidUnicodeEscape_tooManyDigits_variable() {
+    ParserTestCase.parse4("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]);
+  }
+  void test_libraryDirectiveNotFirst_afterPart() {
+    CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "part 'a.dart';\nlibrary l;", [ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST]);
+    JUnitTestCase.assertNotNull(unit);
+  }
+  void test_missingAssignableSelector_identifiersAssigned() {
+    ParserTestCase.parse4("parseExpression", "x.y = y;", []);
+  }
+  void test_missingAssignableSelector_primarySelectorPostfix() {
+    ParserTestCase.parse4("parseExpression", "x(y)(z)++", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]);
+  }
+  void test_missingAssignableSelector_selector() {
+    ParserTestCase.parse4("parseExpression", "x(y)(z).a++", []);
+  }
+  void test_missingAssignableSelector_superPrimaryExpression() {
+    SuperExpression expression = ParserTestCase.parse4("parsePrimaryExpression", "super", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]);
+    JUnitTestCase.assertNotNull(expression.keyword);
+  }
+  void test_missingAssignableSelector_superPropertyAccessAssigned() {
+    ParserTestCase.parse4("parseExpression", "super.x = x;", []);
+  }
+  void test_missingCatchOrFinally() {
+    TryStatement statement = ParserTestCase.parse4("parseTryStatement", "try {}", [ParserErrorCode.MISSING_CATCH_OR_FINALLY]);
+    JUnitTestCase.assertNotNull(statement);
+  }
+  void test_missingClassBody() {
+    ParserTestCase.parse4("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]);
+  }
+  void test_missingFunctionBody_emptyNotAllowed() {
+    ParserTestCase.parse3("parseFunctionBody", <Object> [false, false], ";", [ParserErrorCode.MISSING_FUNCTION_BODY]);
+  }
+  void test_missingFunctionBody_invalid() {
+    ParserTestCase.parse3("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]);
+  }
+  void test_missingFunctionParameters_local_void_expression() {
+    ParserTestCase.parse4("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]);
+  }
+  void test_missingFunctionParameters_topLevel_nonVoid_expression() {
+    ParserTestCase.parse4("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]);
+  }
+  void test_missingFunctionParameters_topLevel_void_expression() {
+    ParserTestCase.parse4("parseCompilationUnit", "void f => x;", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
+  }
+  void test_missingIdentifier_functionDeclaration_returnTypeWithoutName() {
+    ParserTestCase.parse4("parseFunctionDeclarationStatement", "A<T> () {}", [ParserErrorCode.MISSING_IDENTIFIER]);
+  }
+  void test_missingIdentifier_number() {
+    SimpleIdentifier expression = ParserTestCase.parse4("parseSimpleIdentifier", "1", [ParserErrorCode.MISSING_IDENTIFIER]);
+    JUnitTestCase.assertTrue(expression.isSynthetic());
+  }
+  void test_missingNameInLibraryDirective() {
+    CompilationUnit unit = ParserTestCase.parse4("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]);
+    JUnitTestCase.assertNotNull(unit);
+  }
+  void test_missingTypedefParameters_nonVoid() {
+    ParserTestCase.parse4("parseCompilationUnit", "typedef int F;", [ParserErrorCode.MISSING_TYPEDEF_PARAMETERS]);
+  }
+  void test_missingTypedefParameters_typeParameters() {
+    ParserTestCase.parse4("parseCompilationUnit", "typedef F<E>;", [ParserErrorCode.MISSING_TYPEDEF_PARAMETERS]);
+  }
+  void test_missingTypedefParameters_void() {
+    ParserTestCase.parse4("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]);
+  }
+  void test_mixedParameterGroups_namedPositional() {
+    ParserTestCase.parse4("parseFormalParameterList", "(a, {b}, [c])", [ParserErrorCode.MIXED_PARAMETER_GROUPS]);
+  }
+  void test_mixedParameterGroups_positionalNamed() {
+    ParserTestCase.parse4("parseFormalParameterList", "(a, [b], {c})", [ParserErrorCode.MIXED_PARAMETER_GROUPS]);
+  }
+  void test_multipleLibraryDirectives() {
+    ParserTestCase.parse4("parseCompilationUnit", "library l; library m;", [ParserErrorCode.MULTIPLE_LIBRARY_DIRECTIVES]);
+  }
+  void test_multipleNamedParameterGroups() {
+    ParserTestCase.parse4("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]);
+  }
+  void test_multiplePositionalParameterGroups() {
+    ParserTestCase.parse4("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]);
+  }
+  void test_namedParameterOutsideGroup() {
+    ParserTestCase.parse4("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]);
+  }
+  void test_nonConstructorFactory_method() {
+    ParserTestCase.parse3("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]);
+    JUnitTestCase.assertNotNull(unit);
+  }
+  void test_nonIdentifierLibraryName_partOf() {
+    CompilationUnit unit = ParserTestCase.parse4("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]);
+  }
+  void test_nonPartOfDirectiveInPart_before() {
+    ParserTestCase.parse4("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]);
+  }
+  void test_positionalAfterNamedArgument() {
+    ParserTestCase.parse4("parseArgumentList", "(x: 1, 2)", [ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT]);
+  }
+  void test_positionalParameterOutsideGroup() {
+    ParserTestCase.parse4("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]);
+  }
+  void test_staticAfterFinal() {
+    ParserTestCase.parse3("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]);
+  }
+  void test_staticConstructor() {
+    ParserTestCase.parse3("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]);
+  }
+  void test_staticOperator_returnType() {
+    ParserTestCase.parse3("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]);
+  }
+  void test_staticTopLevelDeclaration_typedef() {
+    ParserTestCase.parse4("parseCompilationUnit", "static typedef F();", [ParserErrorCode.STATIC_TOP_LEVEL_DECLARATION]);
+  }
+  void test_staticTopLevelDeclaration_variable() {
+    ParserTestCase.parse4("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]);
+  }
+  void test_unexpectedToken_semicolonBetweenCompilationUnitMembers() {
+    ParserTestCase.parse4("parseCompilationUnit", "int x; ; int y;", [ParserErrorCode.UNEXPECTED_TOKEN]);
+  }
+  void test_useOfUnaryPlusOperator() {
+    ParserTestCase.parse4("parseUnaryExpression", "+x", [ParserErrorCode.USE_OF_UNARY_PLUS_OPERATOR]);
+  }
+  void test_varClass() {
+    ParserTestCase.parse4("parseCompilationUnit", "var class C {}", [ParserErrorCode.VAR_CLASS]);
+  }
+  void test_varConstructor() {
+    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "var C() {}", [ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE]);
+  }
+  void test_varReturnType() {
+    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "var m() {}", [ParserErrorCode.VAR_RETURN_TYPE]);
+  }
+  void test_varTypedef() {
+    ParserTestCase.parse4("parseCompilationUnit", "var typedef F();", [ParserErrorCode.VAR_TYPEDEF]);
+  }
+  void test_voidField_initializer() {
+    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "void x = 0;", [ParserErrorCode.VOID_VARIABLE]);
+  }
+  void test_voidField_noInitializer() {
+    ParserTestCase.parse3("parseClassMember", <Object> ["C"], "void x;", [ParserErrorCode.VOID_VARIABLE]);
+  }
+  void test_voidParameter() {
+    ParserTestCase.parse4("parseNormalFormalParameter", "void a)", [ParserErrorCode.VOID_PARAMETER]);
+  }
+  void test_withBeforeExtends() {
+    ParserTestCase.parse4("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]);
+  }
+  void test_wrongSeparatorForNamedParameter() {
+    ParserTestCase.parse4("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]);
+  }
+  static dartSuite() {
+    _ut.group('ErrorParserTest', () {
+      _ut.test('test_abstractClassMember_constructor', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_abstractClassMember_constructor);
+      });
+      _ut.test('test_abstractClassMember_field', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_abstractClassMember_field);
+      });
+      _ut.test('test_abstractClassMember_getter', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_abstractClassMember_getter);
+      });
+      _ut.test('test_abstractClassMember_method', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_abstractClassMember_method);
+      });
+      _ut.test('test_abstractClassMember_setter', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_abstractClassMember_setter);
+      });
+      _ut.test('test_abstractTopLevelFunction_function', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_abstractTopLevelFunction_function);
+      });
+      _ut.test('test_abstractTopLevelFunction_getter', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_abstractTopLevelFunction_getter);
+      });
+      _ut.test('test_abstractTopLevelFunction_setter', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_abstractTopLevelFunction_setter);
+      });
+      _ut.test('test_abstractTopLevelVariable', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_abstractTopLevelVariable);
+      });
+      _ut.test('test_abstractTypeDef', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_abstractTypeDef);
+      });
+      _ut.test('test_breakOutsideOfLoop_breakInDoStatement', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_breakOutsideOfLoop_breakInDoStatement);
+      });
+      _ut.test('test_breakOutsideOfLoop_breakInForStatement', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_breakOutsideOfLoop_breakInForStatement);
+      });
+      _ut.test('test_breakOutsideOfLoop_breakInIfStatement', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_breakOutsideOfLoop_breakInIfStatement);
+      });
+      _ut.test('test_breakOutsideOfLoop_breakInSwitchStatement', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_breakOutsideOfLoop_breakInSwitchStatement);
+      });
+      _ut.test('test_breakOutsideOfLoop_breakInWhileStatement', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_breakOutsideOfLoop_breakInWhileStatement);
+      });
+      _ut.test('test_breakOutsideOfLoop_functionExpression_inALoop', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_breakOutsideOfLoop_functionExpression_inALoop);
+      });
+      _ut.test('test_breakOutsideOfLoop_functionExpression_withALoop', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_breakOutsideOfLoop_functionExpression_withALoop);
+      });
+      _ut.test('test_builtInIdentifierAsTypeDefName', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_builtInIdentifierAsTypeDefName);
+      });
+      _ut.test('test_builtInIdentifierAsTypeName', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_builtInIdentifierAsTypeName);
+      });
+      _ut.test('test_builtInIdentifierAsTypeVariableName', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_builtInIdentifierAsTypeVariableName);
+      });
+      _ut.test('test_constAndFinal', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_constAndFinal);
+      });
+      _ut.test('test_constAndVar', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_constAndVar);
+      });
+      _ut.test('test_constClass', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_constClass);
+      });
+      _ut.test('test_constMethod', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_constMethod);
+      });
+      _ut.test('test_constTypedef', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_constTypedef);
+      });
+      _ut.test('test_continueOutsideOfLoop_continueInDoStatement', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_continueOutsideOfLoop_continueInDoStatement);
+      });
+      _ut.test('test_continueOutsideOfLoop_continueInForStatement', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_continueOutsideOfLoop_continueInForStatement);
+      });
+      _ut.test('test_continueOutsideOfLoop_continueInIfStatement', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_continueOutsideOfLoop_continueInIfStatement);
+      });
+      _ut.test('test_continueOutsideOfLoop_continueInSwitchStatement', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_continueOutsideOfLoop_continueInSwitchStatement);
+      });
+      _ut.test('test_continueOutsideOfLoop_continueInWhileStatement', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_continueOutsideOfLoop_continueInWhileStatement);
+      });
+      _ut.test('test_continueOutsideOfLoop_functionExpression_inALoop', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_continueOutsideOfLoop_functionExpression_inALoop);
+      });
+      _ut.test('test_continueOutsideOfLoop_functionExpression_withALoop', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_continueOutsideOfLoop_functionExpression_withALoop);
+      });
+      _ut.test('test_continueWithoutLabelInCase_error', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_continueWithoutLabelInCase_error);
+      });
+      _ut.test('test_continueWithoutLabelInCase_noError', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_continueWithoutLabelInCase_noError);
+      });
+      _ut.test('test_continueWithoutLabelInCase_noError_switchInLoop', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_continueWithoutLabelInCase_noError_switchInLoop);
+      });
+      _ut.test('test_directiveAfterDeclaration_classBeforeDirective', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_directiveAfterDeclaration_classBeforeDirective);
+      });
+      _ut.test('test_directiveAfterDeclaration_classBetweenDirectives', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_directiveAfterDeclaration_classBetweenDirectives);
+      });
+      _ut.test('test_duplicateLabelInSwitchStatement', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_duplicateLabelInSwitchStatement);
+      });
+      _ut.test('test_duplicatedModifier_const', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_duplicatedModifier_const);
+      });
+      _ut.test('test_duplicatedModifier_external', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_duplicatedModifier_external);
+      });
+      _ut.test('test_duplicatedModifier_factory', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_duplicatedModifier_factory);
+      });
+      _ut.test('test_duplicatedModifier_final', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_duplicatedModifier_final);
+      });
+      _ut.test('test_duplicatedModifier_static', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_duplicatedModifier_static);
+      });
+      _ut.test('test_duplicatedModifier_var', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_duplicatedModifier_var);
+      });
+      _ut.test('test_expectedCaseOrDefault', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_expectedCaseOrDefault);
+      });
+      _ut.test('test_expectedStringLiteral', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_expectedStringLiteral);
+      });
+      _ut.test('test_expectedToken_commaMissingInArgumentList', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_expectedToken_commaMissingInArgumentList);
+      });
+      _ut.test('test_expectedToken_semicolonMissingAfterExpression', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_expectedToken_semicolonMissingAfterExpression);
+      });
+      _ut.test('test_expectedToken_whileMissingInDoStatement', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_expectedToken_whileMissingInDoStatement);
+      });
+      _ut.test('test_exportDirectiveAfterPartDirective', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_exportDirectiveAfterPartDirective);
+      });
+      _ut.test('test_externalAfterConst', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_externalAfterConst);
+      });
+      _ut.test('test_externalAfterFactory', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_externalAfterFactory);
+      });
+      _ut.test('test_externalAfterStatic', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_externalAfterStatic);
+      });
+      _ut.test('test_externalClass', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_externalClass);
+      });
+      _ut.test('test_externalConstructorWithBody_factory', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_externalConstructorWithBody_factory);
+      });
+      _ut.test('test_externalConstructorWithBody_named', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_externalConstructorWithBody_named);
+      });
+      _ut.test('test_externalField_const', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_externalField_const);
+      });
+      _ut.test('test_externalField_final', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_externalField_final);
+      });
+      _ut.test('test_externalField_static', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_externalField_static);
+      });
+      _ut.test('test_externalField_typed', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_externalField_typed);
+      });
+      _ut.test('test_externalField_untyped', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_externalField_untyped);
+      });
+      _ut.test('test_externalGetterWithBody', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_externalGetterWithBody);
+      });
+      _ut.test('test_externalMethodWithBody', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_externalMethodWithBody);
+      });
+      _ut.test('test_externalOperatorWithBody', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_externalOperatorWithBody);
+      });
+      _ut.test('test_externalSetterWithBody', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_externalSetterWithBody);
+      });
+      _ut.test('test_externalTypedef', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_externalTypedef);
+      });
+      _ut.test('test_factoryTopLevelDeclaration_class', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_factoryTopLevelDeclaration_class);
+      });
+      _ut.test('test_factoryTopLevelDeclaration_typedef', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_factoryTopLevelDeclaration_typedef);
+      });
+      _ut.test('test_fieldInitializerOutsideConstructor', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_fieldInitializerOutsideConstructor);
+      });
+      _ut.test('test_finalAndVar', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_finalAndVar);
+      });
+      _ut.test('test_finalClass', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_finalClass);
+      });
+      _ut.test('test_finalConstructor', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_finalConstructor);
+      });
+      _ut.test('test_finalMethod', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_finalMethod);
+      });
+      _ut.test('test_finalTypedef', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_finalTypedef);
+      });
+      _ut.test('test_getterWithParameters', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_getterWithParameters);
+      });
+      _ut.test('test_illegalAssignmentToNonAssignable_superAssigned', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_illegalAssignmentToNonAssignable_superAssigned);
+      });
+      _ut.test('test_implementsBeforeExtends', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_implementsBeforeExtends);
+      });
+      _ut.test('test_implementsBeforeWith', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_implementsBeforeWith);
+      });
+      _ut.test('test_importDirectiveAfterPartDirective', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_importDirectiveAfterPartDirective);
+      });
+      _ut.test('test_initializedVariableInForEach', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_initializedVariableInForEach);
+      });
+      _ut.test('test_invalidCodePoint', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_invalidCodePoint);
+      });
+      _ut.test('test_invalidHexEscape_invalidDigit', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_invalidHexEscape_invalidDigit);
+      });
+      _ut.test('test_invalidHexEscape_tooFewDigits', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_invalidHexEscape_tooFewDigits);
+      });
+      _ut.test('test_invalidOperatorForSuper', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_invalidOperatorForSuper);
+      });
+      _ut.test('test_invalidUnicodeEscape_incomplete_noDigits', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_invalidUnicodeEscape_incomplete_noDigits);
+      });
+      _ut.test('test_invalidUnicodeEscape_incomplete_someDigits', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_invalidUnicodeEscape_incomplete_someDigits);
+      });
+      _ut.test('test_invalidUnicodeEscape_invalidDigit', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_invalidUnicodeEscape_invalidDigit);
+      });
+      _ut.test('test_invalidUnicodeEscape_tooFewDigits_fixed', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_invalidUnicodeEscape_tooFewDigits_fixed);
+      });
+      _ut.test('test_invalidUnicodeEscape_tooFewDigits_variable', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_invalidUnicodeEscape_tooFewDigits_variable);
+      });
+      _ut.test('test_invalidUnicodeEscape_tooManyDigits_variable', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_invalidUnicodeEscape_tooManyDigits_variable);
+      });
+      _ut.test('test_libraryDirectiveNotFirst', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_libraryDirectiveNotFirst);
+      });
+      _ut.test('test_libraryDirectiveNotFirst_afterPart', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_libraryDirectiveNotFirst_afterPart);
+      });
+      _ut.test('test_missingAssignableSelector_identifiersAssigned', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingAssignableSelector_identifiersAssigned);
+      });
+      _ut.test('test_missingAssignableSelector_primarySelectorPostfix', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingAssignableSelector_primarySelectorPostfix);
+      });
+      _ut.test('test_missingAssignableSelector_selector', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingAssignableSelector_selector);
+      });
+      _ut.test('test_missingAssignableSelector_superPrimaryExpression', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingAssignableSelector_superPrimaryExpression);
+      });
+      _ut.test('test_missingAssignableSelector_superPropertyAccessAssigned', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingAssignableSelector_superPropertyAccessAssigned);
+      });
+      _ut.test('test_missingCatchOrFinally', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingCatchOrFinally);
+      });
+      _ut.test('test_missingClassBody', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingClassBody);
+      });
+      _ut.test('test_missingConstFinalVarOrType', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingConstFinalVarOrType);
+      });
+      _ut.test('test_missingFunctionBody_emptyNotAllowed', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingFunctionBody_emptyNotAllowed);
+      });
+      _ut.test('test_missingFunctionBody_invalid', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingFunctionBody_invalid);
+      });
+      _ut.test('test_missingFunctionParameters_local_void_block', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingFunctionParameters_local_void_block);
+      });
+      _ut.test('test_missingFunctionParameters_local_void_expression', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingFunctionParameters_local_void_expression);
+      });
+      _ut.test('test_missingFunctionParameters_topLevel_nonVoid_block', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingFunctionParameters_topLevel_nonVoid_block);
+      });
+      _ut.test('test_missingFunctionParameters_topLevel_nonVoid_expression', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingFunctionParameters_topLevel_nonVoid_expression);
+      });
+      _ut.test('test_missingFunctionParameters_topLevel_void_block', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingFunctionParameters_topLevel_void_block);
+      });
+      _ut.test('test_missingFunctionParameters_topLevel_void_expression', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingFunctionParameters_topLevel_void_expression);
+      });
+      _ut.test('test_missingIdentifier_functionDeclaration_returnTypeWithoutName', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingIdentifier_functionDeclaration_returnTypeWithoutName);
+      });
+      _ut.test('test_missingIdentifier_number', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingIdentifier_number);
+      });
+      _ut.test('test_missingNameInLibraryDirective', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingNameInLibraryDirective);
+      });
+      _ut.test('test_missingNameInPartOfDirective', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingNameInPartOfDirective);
+      });
+      _ut.test('test_missingTypedefParameters_nonVoid', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingTypedefParameters_nonVoid);
+      });
+      _ut.test('test_missingTypedefParameters_typeParameters', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingTypedefParameters_typeParameters);
+      });
+      _ut.test('test_missingTypedefParameters_void', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingTypedefParameters_void);
+      });
+      _ut.test('test_missingVariableInForEach', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingVariableInForEach);
+      });
+      _ut.test('test_mixedParameterGroups_namedPositional', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_mixedParameterGroups_namedPositional);
+      });
+      _ut.test('test_mixedParameterGroups_positionalNamed', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_mixedParameterGroups_positionalNamed);
+      });
+      _ut.test('test_multipleLibraryDirectives', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_multipleLibraryDirectives);
+      });
+      _ut.test('test_multipleNamedParameterGroups', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_multipleNamedParameterGroups);
+      });
+      _ut.test('test_multiplePartOfDirectives', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_multiplePartOfDirectives);
+      });
+      _ut.test('test_multiplePositionalParameterGroups', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_multiplePositionalParameterGroups);
+      });
+      _ut.test('test_multipleVariablesInForEach', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_multipleVariablesInForEach);
+      });
+      _ut.test('test_namedParameterOutsideGroup', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_namedParameterOutsideGroup);
+      });
+      _ut.test('test_nonConstructorFactory_field', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_nonConstructorFactory_field);
+      });
+      _ut.test('test_nonConstructorFactory_method', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_nonConstructorFactory_method);
+      });
+      _ut.test('test_nonIdentifierLibraryName_library', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_nonIdentifierLibraryName_library);
+      });
+      _ut.test('test_nonIdentifierLibraryName_partOf', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_nonIdentifierLibraryName_partOf);
+      });
+      _ut.test('test_nonPartOfDirectiveInPart_after', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_nonPartOfDirectiveInPart_after);
+      });
+      _ut.test('test_nonPartOfDirectiveInPart_before', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_nonPartOfDirectiveInPart_before);
+      });
+      _ut.test('test_nonUserDefinableOperator', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_nonUserDefinableOperator);
+      });
+      _ut.test('test_positionalAfterNamedArgument', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_positionalAfterNamedArgument);
+      });
+      _ut.test('test_positionalParameterOutsideGroup', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_positionalParameterOutsideGroup);
+      });
+      _ut.test('test_staticAfterConst', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_staticAfterConst);
+      });
+      _ut.test('test_staticAfterFinal', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_staticAfterFinal);
+      });
+      _ut.test('test_staticAfterVar', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_staticAfterVar);
+      });
+      _ut.test('test_staticConstructor', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_staticConstructor);
+      });
+      _ut.test('test_staticOperator_noReturnType', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_staticOperator_noReturnType);
+      });
+      _ut.test('test_staticOperator_returnType', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_staticOperator_returnType);
+      });
+      _ut.test('test_staticTopLevelDeclaration_class', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_staticTopLevelDeclaration_class);
+      });
+      _ut.test('test_staticTopLevelDeclaration_typedef', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_staticTopLevelDeclaration_typedef);
+      });
+      _ut.test('test_staticTopLevelDeclaration_variable', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_staticTopLevelDeclaration_variable);
+      });
+      _ut.test('test_unexpectedToken_semicolonBetweenClassMembers', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_unexpectedToken_semicolonBetweenClassMembers);
+      });
+      _ut.test('test_unexpectedToken_semicolonBetweenCompilationUnitMembers', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_unexpectedToken_semicolonBetweenCompilationUnitMembers);
+      });
+      _ut.test('test_useOfUnaryPlusOperator', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_useOfUnaryPlusOperator);
+      });
+      _ut.test('test_varClass', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_varClass);
+      });
+      _ut.test('test_varConstructor', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_varConstructor);
+      });
+      _ut.test('test_varReturnType', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_varReturnType);
+      });
+      _ut.test('test_varTypedef', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_varTypedef);
+      });
+      _ut.test('test_voidField_initializer', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_voidField_initializer);
+      });
+      _ut.test('test_voidField_noInitializer', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_voidField_noInitializer);
+      });
+      _ut.test('test_voidParameter', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_voidParameter);
+      });
+      _ut.test('test_withBeforeExtends', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_withBeforeExtends);
+      });
+      _ut.test('test_withWithoutExtends', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_withWithoutExtends);
+      });
+      _ut.test('test_wrongSeparatorForNamedParameter', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_wrongSeparatorForNamedParameter);
+      });
+      _ut.test('test_wrongSeparatorForPositionalParameter', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_wrongSeparatorForPositionalParameter);
+      });
+    });
+  }
+}
+main() {
+  ComplexParserTest.dartSuite();
+  ErrorParserTest.dartSuite();
+  RecoveryParserTest.dartSuite();
+  SimpleParserTest.dartSuite();
+}
+Map<String, MethodTrampoline> _methodTable_Parser = <String, MethodTrampoline> {
+  'parseCompilationUnit_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseCompilationUnit(arg0)),
+  'parseExpression_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseExpression(arg0)),
+  'parseStatement_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseStatement(arg0)),
+  'parseStatements_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseStatements(arg0)),
+  'advance_0': new MethodTrampoline(0, (Parser target) => target.advance()),
+  'appendScalarValue_5': new MethodTrampoline(5, (Parser target, arg0, arg1, arg2, arg3, arg4) => target.appendScalarValue(arg0, arg1, arg2, arg3, arg4)),
+  'computeStringValue_1': new MethodTrampoline(1, (Parser target, arg0) => target.computeStringValue(arg0)),
+  'createSyntheticIdentifier_0': new MethodTrampoline(0, (Parser target) => target.createSyntheticIdentifier()),
+  'createSyntheticStringLiteral_0': new MethodTrampoline(0, (Parser target) => target.createSyntheticStringLiteral()),
+  'createSyntheticToken_1': new MethodTrampoline(1, (Parser target, arg0) => target.createSyntheticToken(arg0)),
+  'ensureAssignable_1': new MethodTrampoline(1, (Parser target, arg0) => target.ensureAssignable(arg0)),
+  'expect_1': new MethodTrampoline(1, (Parser target, arg0) => target.expect(arg0)),
+  'hasReturnTypeInTypeAlias_0': new MethodTrampoline(0, (Parser target) => target.hasReturnTypeInTypeAlias()),
+  'isFunctionDeclaration_0': new MethodTrampoline(0, (Parser target) => target.isFunctionDeclaration()),
+  'isFunctionExpression_1': new MethodTrampoline(1, (Parser target, arg0) => target.isFunctionExpression(arg0)),
+  'isHexDigit_1': new MethodTrampoline(1, (Parser target, arg0) => target.isHexDigit(arg0)),
+  'isInitializedVariableDeclaration_0': new MethodTrampoline(0, (Parser target) => target.isInitializedVariableDeclaration()),
+  'isSwitchMember_0': new MethodTrampoline(0, (Parser target) => target.isSwitchMember()),
+  'lexicallyFirst_1': new MethodTrampoline(1, (Parser target, arg0) => target.lexicallyFirst(arg0)),
+  'matches_1': new MethodTrampoline(1, (Parser target, arg0) => target.matches(arg0)),
+  'matches_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.matches3(arg0, arg1)),
+  'matchesAny_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.matchesAny(arg0, arg1)),
+  'matchesIdentifier_0': new MethodTrampoline(0, (Parser target) => target.matchesIdentifier()),
+  'matchesIdentifier_1': new MethodTrampoline(1, (Parser target, arg0) => target.matchesIdentifier2(arg0)),
+  'optional_1': new MethodTrampoline(1, (Parser target, arg0) => target.optional(arg0)),
+  'parseAdditiveExpression_0': new MethodTrampoline(0, (Parser target) => target.parseAdditiveExpression()),
+  'parseAnnotation_0': new MethodTrampoline(0, (Parser target) => target.parseAnnotation()),
+  'parseArgument_0': new MethodTrampoline(0, (Parser target) => target.parseArgument()),
+  'parseArgumentDefinitionTest_0': new MethodTrampoline(0, (Parser target) => target.parseArgumentDefinitionTest()),
+  'parseArgumentList_0': new MethodTrampoline(0, (Parser target) => target.parseArgumentList()),
+  'parseAssertStatement_0': new MethodTrampoline(0, (Parser target) => target.parseAssertStatement()),
+  'parseAssignableExpression_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseAssignableExpression(arg0)),
+  'parseAssignableSelector_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.parseAssignableSelector(arg0, arg1)),
+  'parseBitwiseAndExpression_0': new MethodTrampoline(0, (Parser target) => target.parseBitwiseAndExpression()),
+  'parseBitwiseOrExpression_0': new MethodTrampoline(0, (Parser target) => target.parseBitwiseOrExpression()),
+  'parseBitwiseXorExpression_0': new MethodTrampoline(0, (Parser target) => target.parseBitwiseXorExpression()),
+  'parseBlock_0': new MethodTrampoline(0, (Parser target) => target.parseBlock()),
+  'parseBreakStatement_0': new MethodTrampoline(0, (Parser target) => target.parseBreakStatement()),
+  'parseCascadeSection_0': new MethodTrampoline(0, (Parser target) => target.parseCascadeSection()),
+  'parseClassDeclaration_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.parseClassDeclaration(arg0, arg1)),
+  'parseClassMember_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseClassMember(arg0)),
+  'parseClassMembers_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseClassMembers(arg0)),
+  'parseClassTypeAlias_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.parseClassTypeAlias(arg0, arg1)),
+  'parseCombinators_0': new MethodTrampoline(0, (Parser target) => target.parseCombinators()),
+  'parseCommentAndMetadata_0': new MethodTrampoline(0, (Parser target) => target.parseCommentAndMetadata()),
+  'parseCommentReference_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.parseCommentReference(arg0, arg1)),
+  'parseCommentReferences_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseCommentReferences(arg0)),
+  'parseCompilationUnit_0': new MethodTrampoline(0, (Parser target) => target.parseCompilationUnit2()),
+  'parseCompilationUnitMember_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseCompilationUnitMember(arg0)),
+  'parseConditionalExpression_0': new MethodTrampoline(0, (Parser target) => target.parseConditionalExpression()),
+  'parseConstExpression_0': new MethodTrampoline(0, (Parser target) => target.parseConstExpression()),
+  'parseConstructor_8': new MethodTrampoline(8, (Parser target, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) => target.parseConstructor(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)),
+  'parseConstructorFieldInitializer_0': new MethodTrampoline(0, (Parser target) => target.parseConstructorFieldInitializer()),
+  'parseConstructorName_0': new MethodTrampoline(0, (Parser target) => target.parseConstructorName()),
+  'parseContinueStatement_0': new MethodTrampoline(0, (Parser target) => target.parseContinueStatement()),
+  'parseDirective_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseDirective(arg0)),
+  'parseDocumentationComment_0': new MethodTrampoline(0, (Parser target) => target.parseDocumentationComment()),
+  'parseDoStatement_0': new MethodTrampoline(0, (Parser target) => target.parseDoStatement()),
+  'parseEmptyStatement_0': new MethodTrampoline(0, (Parser target) => target.parseEmptyStatement()),
+  'parseEqualityExpression_0': new MethodTrampoline(0, (Parser target) => target.parseEqualityExpression()),
+  'parseExportDirective_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseExportDirective(arg0)),
+  'parseExpression_0': new MethodTrampoline(0, (Parser target) => target.parseExpression2()),
+  'parseExpressionList_0': new MethodTrampoline(0, (Parser target) => target.parseExpressionList()),
+  'parseExpressionWithoutCascade_0': new MethodTrampoline(0, (Parser target) => target.parseExpressionWithoutCascade()),
+  'parseExtendsClause_0': new MethodTrampoline(0, (Parser target) => target.parseExtendsClause()),
+  'parseFinalConstVarOrType_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseFinalConstVarOrType(arg0)),
+  'parseFormalParameter_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseFormalParameter(arg0)),
+  'parseFormalParameterList_0': new MethodTrampoline(0, (Parser target) => target.parseFormalParameterList()),
+  'parseForStatement_0': new MethodTrampoline(0, (Parser target) => target.parseForStatement()),
+  'parseFunctionBody_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.parseFunctionBody(arg0, arg1)),
+  'parseFunctionDeclaration_4': new MethodTrampoline(4, (Parser target, arg0, arg1, arg2, arg3) => target.parseFunctionDeclaration(arg0, arg1, arg2, arg3)),
+  'parseFunctionDeclarationStatement_0': new MethodTrampoline(0, (Parser target) => target.parseFunctionDeclarationStatement()),
+  'parseFunctionDeclarationStatement_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.parseFunctionDeclarationStatement2(arg0, arg1)),
+  'parseFunctionExpression_0': new MethodTrampoline(0, (Parser target) => target.parseFunctionExpression()),
+  'parseFunctionTypeAlias_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.parseFunctionTypeAlias(arg0, arg1)),
+  'parseGetter_4': new MethodTrampoline(4, (Parser target, arg0, arg1, arg2, arg3) => target.parseGetter(arg0, arg1, arg2, arg3)),
+  'parseIdentifierList_0': new MethodTrampoline(0, (Parser target) => target.parseIdentifierList()),
+  'parseIfStatement_0': new MethodTrampoline(0, (Parser target) => target.parseIfStatement()),
+  'parseImplementsClause_0': new MethodTrampoline(0, (Parser target) => target.parseImplementsClause()),
+  'parseImportDirective_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseImportDirective(arg0)),
+  'parseInitializedIdentifierList_4': new MethodTrampoline(4, (Parser target, arg0, arg1, arg2, arg3) => target.parseInitializedIdentifierList(arg0, arg1, arg2, arg3)),
+  'parseInstanceCreationExpression_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseInstanceCreationExpression(arg0)),
+  'parseLibraryDirective_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseLibraryDirective(arg0)),
+  'parseLibraryIdentifier_0': new MethodTrampoline(0, (Parser target) => target.parseLibraryIdentifier()),
+  'parseLibraryName_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.parseLibraryName(arg0, arg1)),
+  'parseListLiteral_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.parseListLiteral(arg0, arg1)),
+  'parseListOrMapLiteral_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseListOrMapLiteral(arg0)),
+  'parseLogicalAndExpression_0': new MethodTrampoline(0, (Parser target) => target.parseLogicalAndExpression()),
+  'parseLogicalOrExpression_0': new MethodTrampoline(0, (Parser target) => target.parseLogicalOrExpression()),
+  'parseMapLiteral_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.parseMapLiteral(arg0, arg1)),
+  'parseMapLiteralEntry_0': new MethodTrampoline(0, (Parser target) => target.parseMapLiteralEntry()),
+  'parseMethodDeclaration_4': new MethodTrampoline(4, (Parser target, arg0, arg1, arg2, arg3) => target.parseMethodDeclaration(arg0, arg1, arg2, arg3)),
+  'parseMethodDeclaration_6': new MethodTrampoline(6, (Parser target, arg0, arg1, arg2, arg3, arg4, arg5) => target.parseMethodDeclaration2(arg0, arg1, arg2, arg3, arg4, arg5)),
+  'parseModifiers_0': new MethodTrampoline(0, (Parser target) => target.parseModifiers()),
+  'parseMultiplicativeExpression_0': new MethodTrampoline(0, (Parser target) => target.parseMultiplicativeExpression()),
+  'parseNewExpression_0': new MethodTrampoline(0, (Parser target) => target.parseNewExpression()),
+  'parseNonLabeledStatement_0': new MethodTrampoline(0, (Parser target) => target.parseNonLabeledStatement()),
+  'parseNormalFormalParameter_0': new MethodTrampoline(0, (Parser target) => target.parseNormalFormalParameter()),
+  'parseOperator_3': new MethodTrampoline(3, (Parser target, arg0, arg1, arg2) => target.parseOperator(arg0, arg1, arg2)),
+  'parseOptionalReturnType_0': new MethodTrampoline(0, (Parser target) => target.parseOptionalReturnType()),
+  'parsePartDirective_1': new MethodTrampoline(1, (Parser target, arg0) => target.parsePartDirective(arg0)),
+  'parsePostfixExpression_0': new MethodTrampoline(0, (Parser target) => target.parsePostfixExpression()),
+  'parsePrefixedIdentifier_0': new MethodTrampoline(0, (Parser target) => target.parsePrefixedIdentifier()),
+  'parsePrimaryExpression_0': new MethodTrampoline(0, (Parser target) => target.parsePrimaryExpression()),
+  'parseRedirectingConstructorInvocation_0': new MethodTrampoline(0, (Parser target) => target.parseRedirectingConstructorInvocation()),
+  'parseRelationalExpression_0': new MethodTrampoline(0, (Parser target) => target.parseRelationalExpression()),
+  'parseReturnStatement_0': new MethodTrampoline(0, (Parser target) => target.parseReturnStatement()),
+  'parseReturnType_0': new MethodTrampoline(0, (Parser target) => target.parseReturnType()),
+  'parseSetter_4': new MethodTrampoline(4, (Parser target, arg0, arg1, arg2, arg3) => target.parseSetter(arg0, arg1, arg2, arg3)),
+  'parseShiftExpression_0': new MethodTrampoline(0, (Parser target) => target.parseShiftExpression()),
+  'parseSimpleIdentifier_0': new MethodTrampoline(0, (Parser target) => target.parseSimpleIdentifier()),
+  'parseSimpleIdentifier_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseSimpleIdentifier2(arg0)),
+  'parseStatement_0': new MethodTrampoline(0, (Parser target) => target.parseStatement2()),
+  'parseStatements_0': new MethodTrampoline(0, (Parser target) => target.parseStatements2()),
+  'parseStringInterpolation_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseStringInterpolation(arg0)),
+  'parseStringLiteral_0': new MethodTrampoline(0, (Parser target) => target.parseStringLiteral()),
+  'parseSuperConstructorInvocation_0': new MethodTrampoline(0, (Parser target) => target.parseSuperConstructorInvocation()),
+  'parseSwitchStatement_0': new MethodTrampoline(0, (Parser target) => target.parseSwitchStatement()),
+  'parseThrowExpression_0': new MethodTrampoline(0, (Parser target) => target.parseThrowExpression()),
+  'parseThrowExpressionWithoutCascade_0': new MethodTrampoline(0, (Parser target) => target.parseThrowExpressionWithoutCascade()),
+  'parseTryStatement_0': new MethodTrampoline(0, (Parser target) => target.parseTryStatement()),
+  'parseTypeAlias_1': new MethodTrampoline(1, (Parser target, arg0) => target.parseTypeAlias(arg0)),
+  'parseTypeArgumentList_0': new MethodTrampoline(0, (Parser target) => target.parseTypeArgumentList()),
+  'parseTypeName_0': new MethodTrampoline(0, (Parser target) => target.parseTypeName()),
+  'parseTypeParameter_0': new MethodTrampoline(0, (Parser target) => target.parseTypeParameter()),
+  'parseTypeParameterList_0': new MethodTrampoline(0, (Parser target) => target.parseTypeParameterList()),
+  'parseUnaryExpression_0': new MethodTrampoline(0, (Parser target) => target.parseUnaryExpression()),
+  'parseVariableDeclaration_0': new MethodTrampoline(0, (Parser target) => target.parseVariableDeclaration()),
+  'parseVariableDeclarationList_0': new MethodTrampoline(0, (Parser target) => target.parseVariableDeclarationList()),
+  'parseVariableDeclarationList_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.parseVariableDeclarationList2(arg0, arg1)),
+  'parseVariableDeclarationStatement_0': new MethodTrampoline(0, (Parser target) => target.parseVariableDeclarationStatement()),
+  'parseWhileStatement_0': new MethodTrampoline(0, (Parser target) => target.parseWhileStatement()),
+  'parseWithClause_0': new MethodTrampoline(0, (Parser target) => target.parseWithClause()),
+  'peek_0': new MethodTrampoline(0, (Parser target) => target.peek()),
+  'peek_1': new MethodTrampoline(1, (Parser target, arg0) => target.peek2(arg0)),
+  'reportError_3': new MethodTrampoline(3, (Parser target, arg0, arg1, arg2) => target.reportError(arg0, arg1, arg2)),
+  'reportError_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target.reportError3(arg0, arg1)),
+  'skipFinalConstVarOrType_1': new MethodTrampoline(1, (Parser target, arg0) => target.skipFinalConstVarOrType(arg0)),
+  'skipFormalParameterList_1': new MethodTrampoline(1, (Parser target, arg0) => target.skipFormalParameterList(arg0)),
+  'skipPastMatchingToken_1': new MethodTrampoline(1, (Parser target, arg0) => target.skipPastMatchingToken(arg0)),
+  'skipPrefixedIdentifier_1': new MethodTrampoline(1, (Parser target, arg0) => target.skipPrefixedIdentifier(arg0)),
+  'skipReturnType_1': new MethodTrampoline(1, (Parser target, arg0) => target.skipReturnType(arg0)),
+  'skipSimpleIdentifier_1': new MethodTrampoline(1, (Parser target, arg0) => target.skipSimpleIdentifier(arg0)),
+  'skipStringInterpolation_1': new MethodTrampoline(1, (Parser target, arg0) => target.skipStringInterpolation(arg0)),
+  'skipStringLiteral_1': new MethodTrampoline(1, (Parser target, arg0) => target.skipStringLiteral(arg0)),
+  'skipTypeArgumentList_1': new MethodTrampoline(1, (Parser target, arg0) => target.skipTypeArgumentList(arg0)),
+  'skipTypeName_1': new MethodTrampoline(1, (Parser target, arg0) => target.skipTypeName(arg0)),
+  'skipTypeParameterList_1': new MethodTrampoline(1, (Parser target, arg0) => target.skipTypeParameterList(arg0)),
+  'translateCharacter_3': new MethodTrampoline(3, (Parser target, arg0, arg1, arg2) => target.translateCharacter(arg0, arg1, arg2)),
+  'validateFormalParameterList_1': new MethodTrampoline(1, (Parser target, arg0) => target.validateFormalParameterList(arg0)),
+  'validateModifiersForClass_1': new MethodTrampoline(1, (Parser target, arg0) => target.validateModifiersForClass(arg0)),
+  'validateModifiersForConstructor_1': new MethodTrampoline(1, (Parser target, arg0) => target.validateModifiersForConstructor(arg0)),
+  'validateModifiersForField_1': new MethodTrampoline(1, (Parser target, arg0) => target.validateModifiersForField(arg0)),
+  'validateModifiersForGetterOrSetterOrMethod_1': new MethodTrampoline(1, (Parser target, arg0) => target.validateModifiersForGetterOrSetterOrMethod(arg0)),
+  'validateModifiersForOperator_1': new MethodTrampoline(1, (Parser target, arg0) => target.validateModifiersForOperator(arg0)),
+  'validateModifiersForTopLevelDeclaration_1': new MethodTrampoline(1, (Parser target, arg0) => target.validateModifiersForTopLevelDeclaration(arg0)),
+  'validateModifiersForTopLevelFunction_1': new MethodTrampoline(1, (Parser target, arg0) => target.validateModifiersForTopLevelFunction(arg0)),
+  'validateModifiersForTopLevelVariable_1': new MethodTrampoline(1, (Parser target, arg0) => target.validateModifiersForTopLevelVariable(arg0)),
+  'validateModifiersForTypedef_1': new MethodTrampoline(1, (Parser target, arg0) => target.validateModifiersForTypedef(arg0)),};
+
+
+Object invokeParserMethodImpl(Parser parser, String methodName, List<Object> objects, Token tokenStream) {
+  parser.currentToken = tokenStream;
+  MethodTrampoline method = _methodTable_Parser['${methodName}_${objects.length}'];
+  return method.invoke(parser, objects);
+}
diff --git a/pkg/analyzer-experimental/test/generated/scanner_test.dart b/pkg/analyzer-experimental/test/generated/scanner_test.dart
new file mode 100644
index 0000000..3fce7f6
--- /dev/null
+++ b/pkg/analyzer-experimental/test/generated/scanner_test.dart
@@ -0,0 +1,2063 @@
+// 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.scanner_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:unittest/unittest.dart' as _ut;
+import 'test_support.dart';
+
+class CharBufferScannerTest extends AbstractScannerTest {
+  Token scan(String source, GatheringErrorListener listener) {
+    CharBuffer buffer = CharBuffer.wrap(source);
+    CharBufferScanner scanner = new CharBufferScanner(null, buffer, listener);
+    Token result = scanner.tokenize();
+    listener.setLineInfo(new TestSource(), scanner.lineStarts);
+    return result;
+  }
+  static dartSuite() {
+    _ut.group('CharBufferScannerTest', () {
+      _ut.test('test_ampersand', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_ampersand);
+      });
+      _ut.test('test_ampersand_ampersand', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_ampersand_ampersand);
+      });
+      _ut.test('test_ampersand_eq', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_ampersand_eq);
+      });
+      _ut.test('test_at', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_at);
+      });
+      _ut.test('test_backping', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_backping);
+      });
+      _ut.test('test_backslash', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_backslash);
+      });
+      _ut.test('test_bang', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_bang);
+      });
+      _ut.test('test_bang_eq', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_bang_eq);
+      });
+      _ut.test('test_bar', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_bar);
+      });
+      _ut.test('test_bar_bar', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_bar_bar);
+      });
+      _ut.test('test_bar_eq', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_bar_eq);
+      });
+      _ut.test('test_caret', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_caret);
+      });
+      _ut.test('test_caret_eq', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_caret_eq);
+      });
+      _ut.test('test_close_curly_bracket', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_close_curly_bracket);
+      });
+      _ut.test('test_close_paren', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_close_paren);
+      });
+      _ut.test('test_close_quare_bracket', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_close_quare_bracket);
+      });
+      _ut.test('test_colon', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_colon);
+      });
+      _ut.test('test_comma', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_comma);
+      });
+      _ut.test('test_comment_multi', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_comment_multi);
+      });
+      _ut.test('test_comment_multi_unterminated', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_comment_multi_unterminated);
+      });
+      _ut.test('test_comment_nested', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_comment_nested);
+      });
+      _ut.test('test_comment_single', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_comment_single);
+      });
+      _ut.test('test_double_both_E', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_double_both_E);
+      });
+      _ut.test('test_double_both_e', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_double_both_e);
+      });
+      _ut.test('test_double_fraction', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_double_fraction);
+      });
+      _ut.test('test_double_fraction_D', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_double_fraction_D);
+      });
+      _ut.test('test_double_fraction_E', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_double_fraction_E);
+      });
+      _ut.test('test_double_fraction_Ed', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_double_fraction_Ed);
+      });
+      _ut.test('test_double_fraction_d', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_double_fraction_d);
+      });
+      _ut.test('test_double_fraction_e', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_double_fraction_e);
+      });
+      _ut.test('test_double_fraction_ed', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_double_fraction_ed);
+      });
+      _ut.test('test_double_missingDigitInExponent', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_double_missingDigitInExponent);
+      });
+      _ut.test('test_double_whole_D', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_double_whole_D);
+      });
+      _ut.test('test_double_whole_E', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_double_whole_E);
+      });
+      _ut.test('test_double_whole_Ed', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_double_whole_Ed);
+      });
+      _ut.test('test_double_whole_d', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_double_whole_d);
+      });
+      _ut.test('test_double_whole_e', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_double_whole_e);
+      });
+      _ut.test('test_double_whole_ed', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_double_whole_ed);
+      });
+      _ut.test('test_eq', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_eq);
+      });
+      _ut.test('test_eq_eq', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_eq_eq);
+      });
+      _ut.test('test_gt', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_gt);
+      });
+      _ut.test('test_gt_eq', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_gt_eq);
+      });
+      _ut.test('test_gt_gt', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_gt_gt);
+      });
+      _ut.test('test_gt_gt_eq', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_gt_gt_eq);
+      });
+      _ut.test('test_hash', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_hash);
+      });
+      _ut.test('test_hexidecimal', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_hexidecimal);
+      });
+      _ut.test('test_hexidecimal_missingDigit', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_hexidecimal_missingDigit);
+      });
+      _ut.test('test_identifier', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_identifier);
+      });
+      _ut.test('test_illegalChar', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_illegalChar);
+      });
+      _ut.test('test_index', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_index);
+      });
+      _ut.test('test_index_eq', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_index_eq);
+      });
+      _ut.test('test_int', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_int);
+      });
+      _ut.test('test_int_initialZero', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_int_initialZero);
+      });
+      _ut.test('test_keyword_abstract', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_abstract);
+      });
+      _ut.test('test_keyword_as', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_as);
+      });
+      _ut.test('test_keyword_assert', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_assert);
+      });
+      _ut.test('test_keyword_break', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_break);
+      });
+      _ut.test('test_keyword_case', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_case);
+      });
+      _ut.test('test_keyword_catch', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_catch);
+      });
+      _ut.test('test_keyword_class', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_class);
+      });
+      _ut.test('test_keyword_const', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_const);
+      });
+      _ut.test('test_keyword_continue', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_continue);
+      });
+      _ut.test('test_keyword_default', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_default);
+      });
+      _ut.test('test_keyword_do', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_do);
+      });
+      _ut.test('test_keyword_dynamic', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_dynamic);
+      });
+      _ut.test('test_keyword_else', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_else);
+      });
+      _ut.test('test_keyword_export', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_export);
+      });
+      _ut.test('test_keyword_extends', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_extends);
+      });
+      _ut.test('test_keyword_factory', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_factory);
+      });
+      _ut.test('test_keyword_false', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_false);
+      });
+      _ut.test('test_keyword_final', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_final);
+      });
+      _ut.test('test_keyword_finally', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_finally);
+      });
+      _ut.test('test_keyword_for', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_for);
+      });
+      _ut.test('test_keyword_get', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_get);
+      });
+      _ut.test('test_keyword_if', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_if);
+      });
+      _ut.test('test_keyword_implements', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_implements);
+      });
+      _ut.test('test_keyword_import', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_import);
+      });
+      _ut.test('test_keyword_in', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_in);
+      });
+      _ut.test('test_keyword_is', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_is);
+      });
+      _ut.test('test_keyword_library', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_library);
+      });
+      _ut.test('test_keyword_new', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_new);
+      });
+      _ut.test('test_keyword_null', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_null);
+      });
+      _ut.test('test_keyword_operator', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_operator);
+      });
+      _ut.test('test_keyword_part', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_part);
+      });
+      _ut.test('test_keyword_return', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_return);
+      });
+      _ut.test('test_keyword_set', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_set);
+      });
+      _ut.test('test_keyword_static', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_static);
+      });
+      _ut.test('test_keyword_super', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_super);
+      });
+      _ut.test('test_keyword_switch', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_switch);
+      });
+      _ut.test('test_keyword_this', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_this);
+      });
+      _ut.test('test_keyword_throw', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_throw);
+      });
+      _ut.test('test_keyword_true', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_true);
+      });
+      _ut.test('test_keyword_try', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_try);
+      });
+      _ut.test('test_keyword_typedef', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_typedef);
+      });
+      _ut.test('test_keyword_var', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_var);
+      });
+      _ut.test('test_keyword_void', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_void);
+      });
+      _ut.test('test_keyword_while', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_while);
+      });
+      _ut.test('test_keyword_with', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_keyword_with);
+      });
+      _ut.test('test_lt', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_lt);
+      });
+      _ut.test('test_lt_eq', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_lt_eq);
+      });
+      _ut.test('test_lt_lt', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_lt_lt);
+      });
+      _ut.test('test_lt_lt_eq', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_lt_lt_eq);
+      });
+      _ut.test('test_minus', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_minus);
+      });
+      _ut.test('test_minus_eq', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_minus_eq);
+      });
+      _ut.test('test_minus_minus', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_minus_minus);
+      });
+      _ut.test('test_openSquareBracket', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_openSquareBracket);
+      });
+      _ut.test('test_open_curly_bracket', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_open_curly_bracket);
+      });
+      _ut.test('test_open_paren', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_open_paren);
+      });
+      _ut.test('test_open_square_bracket', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_open_square_bracket);
+      });
+      _ut.test('test_percent', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_percent);
+      });
+      _ut.test('test_percent_eq', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_percent_eq);
+      });
+      _ut.test('test_period', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_period);
+      });
+      _ut.test('test_periodAfterNumberNotIncluded_identifier', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_periodAfterNumberNotIncluded_identifier);
+      });
+      _ut.test('test_periodAfterNumberNotIncluded_period', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_periodAfterNumberNotIncluded_period);
+      });
+      _ut.test('test_period_period', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_period_period);
+      });
+      _ut.test('test_period_period_period', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_period_period_period);
+      });
+      _ut.test('test_plus', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_plus);
+      });
+      _ut.test('test_plus_eq', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_plus_eq);
+      });
+      _ut.test('test_plus_plus', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_plus_plus);
+      });
+      _ut.test('test_question', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_question);
+      });
+      _ut.test('test_scriptTag_withArgs', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_scriptTag_withArgs);
+      });
+      _ut.test('test_scriptTag_withSpace', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_scriptTag_withSpace);
+      });
+      _ut.test('test_scriptTag_withoutSpace', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_scriptTag_withoutSpace);
+      });
+      _ut.test('test_semicolon', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_semicolon);
+      });
+      _ut.test('test_slash', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_slash);
+      });
+      _ut.test('test_slash_eq', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_slash_eq);
+      });
+      _ut.test('test_star', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_star);
+      });
+      _ut.test('test_star_eq', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_star_eq);
+      });
+      _ut.test('test_startAndEnd', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_startAndEnd);
+      });
+      _ut.test('test_string_multi_double', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_multi_double);
+      });
+      _ut.test('test_string_multi_interpolation_block', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_multi_interpolation_block);
+      });
+      _ut.test('test_string_multi_interpolation_identifier', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_multi_interpolation_identifier);
+      });
+      _ut.test('test_string_multi_single', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_multi_single);
+      });
+      _ut.test('test_string_multi_unterminated', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_multi_unterminated);
+      });
+      _ut.test('test_string_raw_multi_double', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_multi_double);
+      });
+      _ut.test('test_string_raw_multi_single', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_multi_single);
+      });
+      _ut.test('test_string_raw_multi_unterminated', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_multi_unterminated);
+      });
+      _ut.test('test_string_raw_simple_double', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_simple_double);
+      });
+      _ut.test('test_string_raw_simple_single', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_simple_single);
+      });
+      _ut.test('test_string_raw_simple_unterminated_eof', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_simple_unterminated_eof);
+      });
+      _ut.test('test_string_raw_simple_unterminated_eol', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_simple_unterminated_eol);
+      });
+      _ut.test('test_string_simple_double', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_double);
+      });
+      _ut.test('test_string_simple_escapedDollar', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_escapedDollar);
+      });
+      _ut.test('test_string_simple_interpolation_block', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_interpolation_block);
+      });
+      _ut.test('test_string_simple_interpolation_blockWithNestedMap', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_interpolation_blockWithNestedMap);
+      });
+      _ut.test('test_string_simple_interpolation_firstAndLast', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_interpolation_firstAndLast);
+      });
+      _ut.test('test_string_simple_interpolation_identifier', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_interpolation_identifier);
+      });
+      _ut.test('test_string_simple_single', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_single);
+      });
+      _ut.test('test_string_simple_unterminated_eof', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_unterminated_eof);
+      });
+      _ut.test('test_string_simple_unterminated_eol', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_unterminated_eol);
+      });
+      _ut.test('test_tilde', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_tilde);
+      });
+      _ut.test('test_tilde_slash', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_tilde_slash);
+      });
+      _ut.test('test_tilde_slash_eq', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_tilde_slash_eq);
+      });
+      _ut.test('test_unclosedPairInInterpolation', () {
+        final __test = new CharBufferScannerTest();
+        runJUnitTest(__test, __test.test_unclosedPairInInterpolation);
+      });
+    });
+  }
+}
+/**
+ * Instances of the class {@code TokenStreamValidator} are used to validate the correct construction
+ * of a stream of tokens.
+ */
+class TokenStreamValidator {
+  /**
+   * Validate that the stream of tokens that starts with the given token is correct.
+   * @param token the first token in the stream of tokens to be validated
+   */
+  void validate(Token token) {
+    StringBuffer builder = new StringBuffer();
+    validateStream(builder, token);
+    if (builder.length > 0) {
+      JUnitTestCase.fail(builder.toString());
+    }
+  }
+  void validateStream(StringBuffer builder, Token token) {
+    if (token == null) {
+      return;
+    }
+    Token previousToken = null;
+    int previousEnd = -1;
+    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) {
+        if (currentToken is! BeginToken) {
+          builder.add("\r\nExpected BeginToken, found ");
+          builder.add(currentToken.runtimeType.toString());
+          builder.add(" ");
+          writeToken(builder, currentToken);
+        }
+      }
+      int currentStart = currentToken.offset;
+      int currentLength = currentToken.length;
+      int currentEnd = currentStart + currentLength - 1;
+      if (currentStart <= previousEnd) {
+        builder.add("\r\nInvalid token sequence: ");
+        writeToken(builder, previousToken);
+        builder.add(" followed by ");
+        writeToken(builder, currentToken);
+      }
+      previousEnd = currentEnd;
+      previousToken = currentToken;
+      currentToken = currentToken.next;
+    }
+  }
+  void writeToken(StringBuffer builder, Token token) {
+    builder.add("[");
+    builder.add(token.type);
+    builder.add(", '");
+    builder.add(token.lexeme);
+    builder.add("', ");
+    builder.add(token.offset);
+    builder.add(", ");
+    builder.add(token.length);
+    builder.add("]");
+  }
+}
+class TokenTypeTest extends EngineTestCase {
+  void test_isOperator() {
+    JUnitTestCase.assertTrue(TokenType.AMPERSAND.isOperator());
+    JUnitTestCase.assertTrue(TokenType.AMPERSAND_AMPERSAND.isOperator());
+    JUnitTestCase.assertTrue(TokenType.AMPERSAND_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.BANG.isOperator());
+    JUnitTestCase.assertTrue(TokenType.BANG_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.BAR.isOperator());
+    JUnitTestCase.assertTrue(TokenType.BAR_BAR.isOperator());
+    JUnitTestCase.assertTrue(TokenType.BAR_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.CARET.isOperator());
+    JUnitTestCase.assertTrue(TokenType.CARET_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.EQ_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.GT.isOperator());
+    JUnitTestCase.assertTrue(TokenType.GT_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.GT_GT.isOperator());
+    JUnitTestCase.assertTrue(TokenType.GT_GT_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.INDEX.isOperator());
+    JUnitTestCase.assertTrue(TokenType.INDEX_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.IS.isOperator());
+    JUnitTestCase.assertTrue(TokenType.LT.isOperator());
+    JUnitTestCase.assertTrue(TokenType.LT_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.LT_LT.isOperator());
+    JUnitTestCase.assertTrue(TokenType.LT_LT_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.MINUS.isOperator());
+    JUnitTestCase.assertTrue(TokenType.MINUS_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.MINUS_MINUS.isOperator());
+    JUnitTestCase.assertTrue(TokenType.PERCENT.isOperator());
+    JUnitTestCase.assertTrue(TokenType.PERCENT_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.PERIOD_PERIOD.isOperator());
+    JUnitTestCase.assertTrue(TokenType.PLUS.isOperator());
+    JUnitTestCase.assertTrue(TokenType.PLUS_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.PLUS_PLUS.isOperator());
+    JUnitTestCase.assertTrue(TokenType.QUESTION.isOperator());
+    JUnitTestCase.assertTrue(TokenType.SLASH.isOperator());
+    JUnitTestCase.assertTrue(TokenType.SLASH_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.STAR.isOperator());
+    JUnitTestCase.assertTrue(TokenType.STAR_EQ.isOperator());
+    JUnitTestCase.assertTrue(TokenType.TILDE.isOperator());
+    JUnitTestCase.assertTrue(TokenType.TILDE_SLASH.isOperator());
+    JUnitTestCase.assertTrue(TokenType.TILDE_SLASH_EQ.isOperator());
+  }
+  void test_isUserDefinableOperator() {
+    JUnitTestCase.assertTrue(TokenType.AMPERSAND.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.BAR.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.CARET.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.EQ_EQ.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.GT.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.GT_EQ.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.GT_GT.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.INDEX.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.INDEX_EQ.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.LT.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.LT_EQ.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.LT_LT.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.MINUS.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.PERCENT.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.PLUS.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.SLASH.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.STAR.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.TILDE.isUserDefinableOperator());
+    JUnitTestCase.assertTrue(TokenType.TILDE_SLASH.isUserDefinableOperator());
+  }
+  static dartSuite() {
+    _ut.group('TokenTypeTest', () {
+      _ut.test('test_isOperator', () {
+        final __test = new TokenTypeTest();
+        runJUnitTest(__test, __test.test_isOperator);
+      });
+      _ut.test('test_isUserDefinableOperator', () {
+        final __test = new TokenTypeTest();
+        runJUnitTest(__test, __test.test_isUserDefinableOperator);
+      });
+    });
+  }
+}
+/**
+ * The class {@code TokenFactory} defines utility methods that can be used to create tokens.
+ */
+class TokenFactory {
+  static Token token(Keyword keyword) => new KeywordToken(keyword, 0);
+  static Token token2(String lexeme) => new StringToken(TokenType.STRING, lexeme, 0);
+  static Token token3(TokenType type) => new Token(type, 0);
+  static Token token4(TokenType type, String lexeme) => new StringToken(type, lexeme, 0);
+  /**
+   * Prevent the creation of instances of this class.
+   */
+  TokenFactory() {
+  }
+}
+class KeywordStateTest extends JUnitTestCase {
+  void test_KeywordState() {
+    List<Keyword> keywords = Keyword.values;
+    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);
+    }
+    KeywordState firstState = KeywordState.KEYWORD_STATE;
+    for (int i = 0; i < textToTest.length; i++) {
+      String text = textToTest[i];
+      int index = 0;
+      int length9 = text.length;
+      KeywordState state = firstState;
+      while (index < length9 && state != null) {
+        state = state.next(text.charCodeAt(index));
+        index++;
+      }
+      if (i < keywordCount) {
+        JUnitTestCase.assertNotNull(state);
+        JUnitTestCase.assertNotNull(state.keyword());
+        JUnitTestCase.assertEquals(keywords[i], state.keyword());
+      } else if (i < keywordCount * 2) {
+        JUnitTestCase.assertNull(state);
+      } else {
+        JUnitTestCase.assertNotNull(state);
+      }
+    }
+  }
+  static dartSuite() {
+    _ut.group('KeywordStateTest', () {
+      _ut.test('test_KeywordState', () {
+        final __test = new KeywordStateTest();
+        runJUnitTest(__test, __test.test_KeywordState);
+      });
+    });
+  }
+}
+class StringScannerTest extends AbstractScannerTest {
+  void test_setSourceStart() {
+    int offsetDelta = 42;
+    GatheringErrorListener listener = new GatheringErrorListener();
+    StringScanner scanner = new StringScanner(null, "a", listener);
+    scanner.setSourceStart(3, 9, offsetDelta);
+    scanner.tokenize();
+    List<int> lineStarts2 = scanner.lineStarts;
+    JUnitTestCase.assertNotNull(lineStarts2);
+    JUnitTestCase.assertEquals(3, lineStarts2.length);
+    JUnitTestCase.assertEquals(33, lineStarts2[2]);
+  }
+  Token scan(String source, GatheringErrorListener listener) {
+    StringScanner scanner = new StringScanner(null, source, listener);
+    Token result = scanner.tokenize();
+    listener.setLineInfo(new TestSource(), scanner.lineStarts);
+    return result;
+  }
+  static dartSuite() {
+    _ut.group('StringScannerTest', () {
+      _ut.test('test_ampersand', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_ampersand);
+      });
+      _ut.test('test_ampersand_ampersand', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_ampersand_ampersand);
+      });
+      _ut.test('test_ampersand_eq', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_ampersand_eq);
+      });
+      _ut.test('test_at', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_at);
+      });
+      _ut.test('test_backping', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_backping);
+      });
+      _ut.test('test_backslash', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_backslash);
+      });
+      _ut.test('test_bang', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_bang);
+      });
+      _ut.test('test_bang_eq', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_bang_eq);
+      });
+      _ut.test('test_bar', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_bar);
+      });
+      _ut.test('test_bar_bar', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_bar_bar);
+      });
+      _ut.test('test_bar_eq', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_bar_eq);
+      });
+      _ut.test('test_caret', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_caret);
+      });
+      _ut.test('test_caret_eq', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_caret_eq);
+      });
+      _ut.test('test_close_curly_bracket', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_close_curly_bracket);
+      });
+      _ut.test('test_close_paren', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_close_paren);
+      });
+      _ut.test('test_close_quare_bracket', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_close_quare_bracket);
+      });
+      _ut.test('test_colon', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_colon);
+      });
+      _ut.test('test_comma', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_comma);
+      });
+      _ut.test('test_comment_multi', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_comment_multi);
+      });
+      _ut.test('test_comment_multi_unterminated', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_comment_multi_unterminated);
+      });
+      _ut.test('test_comment_nested', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_comment_nested);
+      });
+      _ut.test('test_comment_single', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_comment_single);
+      });
+      _ut.test('test_double_both_E', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_double_both_E);
+      });
+      _ut.test('test_double_both_e', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_double_both_e);
+      });
+      _ut.test('test_double_fraction', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_double_fraction);
+      });
+      _ut.test('test_double_fraction_D', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_double_fraction_D);
+      });
+      _ut.test('test_double_fraction_E', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_double_fraction_E);
+      });
+      _ut.test('test_double_fraction_Ed', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_double_fraction_Ed);
+      });
+      _ut.test('test_double_fraction_d', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_double_fraction_d);
+      });
+      _ut.test('test_double_fraction_e', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_double_fraction_e);
+      });
+      _ut.test('test_double_fraction_ed', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_double_fraction_ed);
+      });
+      _ut.test('test_double_missingDigitInExponent', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_double_missingDigitInExponent);
+      });
+      _ut.test('test_double_whole_D', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_double_whole_D);
+      });
+      _ut.test('test_double_whole_E', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_double_whole_E);
+      });
+      _ut.test('test_double_whole_Ed', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_double_whole_Ed);
+      });
+      _ut.test('test_double_whole_d', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_double_whole_d);
+      });
+      _ut.test('test_double_whole_e', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_double_whole_e);
+      });
+      _ut.test('test_double_whole_ed', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_double_whole_ed);
+      });
+      _ut.test('test_eq', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_eq);
+      });
+      _ut.test('test_eq_eq', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_eq_eq);
+      });
+      _ut.test('test_gt', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_gt);
+      });
+      _ut.test('test_gt_eq', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_gt_eq);
+      });
+      _ut.test('test_gt_gt', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_gt_gt);
+      });
+      _ut.test('test_gt_gt_eq', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_gt_gt_eq);
+      });
+      _ut.test('test_hash', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_hash);
+      });
+      _ut.test('test_hexidecimal', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_hexidecimal);
+      });
+      _ut.test('test_hexidecimal_missingDigit', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_hexidecimal_missingDigit);
+      });
+      _ut.test('test_identifier', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_identifier);
+      });
+      _ut.test('test_illegalChar', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_illegalChar);
+      });
+      _ut.test('test_index', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_index);
+      });
+      _ut.test('test_index_eq', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_index_eq);
+      });
+      _ut.test('test_int', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_int);
+      });
+      _ut.test('test_int_initialZero', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_int_initialZero);
+      });
+      _ut.test('test_keyword_abstract', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_abstract);
+      });
+      _ut.test('test_keyword_as', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_as);
+      });
+      _ut.test('test_keyword_assert', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_assert);
+      });
+      _ut.test('test_keyword_break', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_break);
+      });
+      _ut.test('test_keyword_case', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_case);
+      });
+      _ut.test('test_keyword_catch', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_catch);
+      });
+      _ut.test('test_keyword_class', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_class);
+      });
+      _ut.test('test_keyword_const', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_const);
+      });
+      _ut.test('test_keyword_continue', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_continue);
+      });
+      _ut.test('test_keyword_default', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_default);
+      });
+      _ut.test('test_keyword_do', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_do);
+      });
+      _ut.test('test_keyword_dynamic', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_dynamic);
+      });
+      _ut.test('test_keyword_else', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_else);
+      });
+      _ut.test('test_keyword_export', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_export);
+      });
+      _ut.test('test_keyword_extends', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_extends);
+      });
+      _ut.test('test_keyword_factory', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_factory);
+      });
+      _ut.test('test_keyword_false', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_false);
+      });
+      _ut.test('test_keyword_final', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_final);
+      });
+      _ut.test('test_keyword_finally', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_finally);
+      });
+      _ut.test('test_keyword_for', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_for);
+      });
+      _ut.test('test_keyword_get', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_get);
+      });
+      _ut.test('test_keyword_if', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_if);
+      });
+      _ut.test('test_keyword_implements', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_implements);
+      });
+      _ut.test('test_keyword_import', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_import);
+      });
+      _ut.test('test_keyword_in', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_in);
+      });
+      _ut.test('test_keyword_is', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_is);
+      });
+      _ut.test('test_keyword_library', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_library);
+      });
+      _ut.test('test_keyword_new', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_new);
+      });
+      _ut.test('test_keyword_null', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_null);
+      });
+      _ut.test('test_keyword_operator', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_operator);
+      });
+      _ut.test('test_keyword_part', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_part);
+      });
+      _ut.test('test_keyword_return', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_return);
+      });
+      _ut.test('test_keyword_set', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_set);
+      });
+      _ut.test('test_keyword_static', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_static);
+      });
+      _ut.test('test_keyword_super', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_super);
+      });
+      _ut.test('test_keyword_switch', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_switch);
+      });
+      _ut.test('test_keyword_this', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_this);
+      });
+      _ut.test('test_keyword_throw', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_throw);
+      });
+      _ut.test('test_keyword_true', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_true);
+      });
+      _ut.test('test_keyword_try', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_try);
+      });
+      _ut.test('test_keyword_typedef', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_typedef);
+      });
+      _ut.test('test_keyword_var', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_var);
+      });
+      _ut.test('test_keyword_void', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_void);
+      });
+      _ut.test('test_keyword_while', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_while);
+      });
+      _ut.test('test_keyword_with', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_keyword_with);
+      });
+      _ut.test('test_lt', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_lt);
+      });
+      _ut.test('test_lt_eq', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_lt_eq);
+      });
+      _ut.test('test_lt_lt', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_lt_lt);
+      });
+      _ut.test('test_lt_lt_eq', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_lt_lt_eq);
+      });
+      _ut.test('test_minus', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_minus);
+      });
+      _ut.test('test_minus_eq', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_minus_eq);
+      });
+      _ut.test('test_minus_minus', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_minus_minus);
+      });
+      _ut.test('test_openSquareBracket', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_openSquareBracket);
+      });
+      _ut.test('test_open_curly_bracket', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_open_curly_bracket);
+      });
+      _ut.test('test_open_paren', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_open_paren);
+      });
+      _ut.test('test_open_square_bracket', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_open_square_bracket);
+      });
+      _ut.test('test_percent', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_percent);
+      });
+      _ut.test('test_percent_eq', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_percent_eq);
+      });
+      _ut.test('test_period', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_period);
+      });
+      _ut.test('test_periodAfterNumberNotIncluded_identifier', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_periodAfterNumberNotIncluded_identifier);
+      });
+      _ut.test('test_periodAfterNumberNotIncluded_period', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_periodAfterNumberNotIncluded_period);
+      });
+      _ut.test('test_period_period', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_period_period);
+      });
+      _ut.test('test_period_period_period', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_period_period_period);
+      });
+      _ut.test('test_plus', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_plus);
+      });
+      _ut.test('test_plus_eq', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_plus_eq);
+      });
+      _ut.test('test_plus_plus', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_plus_plus);
+      });
+      _ut.test('test_question', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_question);
+      });
+      _ut.test('test_scriptTag_withArgs', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_scriptTag_withArgs);
+      });
+      _ut.test('test_scriptTag_withSpace', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_scriptTag_withSpace);
+      });
+      _ut.test('test_scriptTag_withoutSpace', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_scriptTag_withoutSpace);
+      });
+      _ut.test('test_semicolon', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_semicolon);
+      });
+      _ut.test('test_setSourceStart', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_setSourceStart);
+      });
+      _ut.test('test_slash', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_slash);
+      });
+      _ut.test('test_slash_eq', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_slash_eq);
+      });
+      _ut.test('test_star', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_star);
+      });
+      _ut.test('test_star_eq', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_star_eq);
+      });
+      _ut.test('test_startAndEnd', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_startAndEnd);
+      });
+      _ut.test('test_string_multi_double', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_multi_double);
+      });
+      _ut.test('test_string_multi_interpolation_block', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_multi_interpolation_block);
+      });
+      _ut.test('test_string_multi_interpolation_identifier', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_multi_interpolation_identifier);
+      });
+      _ut.test('test_string_multi_single', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_multi_single);
+      });
+      _ut.test('test_string_multi_unterminated', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_multi_unterminated);
+      });
+      _ut.test('test_string_raw_multi_double', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_multi_double);
+      });
+      _ut.test('test_string_raw_multi_single', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_multi_single);
+      });
+      _ut.test('test_string_raw_multi_unterminated', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_multi_unterminated);
+      });
+      _ut.test('test_string_raw_simple_double', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_simple_double);
+      });
+      _ut.test('test_string_raw_simple_single', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_simple_single);
+      });
+      _ut.test('test_string_raw_simple_unterminated_eof', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_simple_unterminated_eof);
+      });
+      _ut.test('test_string_raw_simple_unterminated_eol', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_simple_unterminated_eol);
+      });
+      _ut.test('test_string_simple_double', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_double);
+      });
+      _ut.test('test_string_simple_escapedDollar', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_escapedDollar);
+      });
+      _ut.test('test_string_simple_interpolation_block', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_interpolation_block);
+      });
+      _ut.test('test_string_simple_interpolation_blockWithNestedMap', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_interpolation_blockWithNestedMap);
+      });
+      _ut.test('test_string_simple_interpolation_firstAndLast', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_interpolation_firstAndLast);
+      });
+      _ut.test('test_string_simple_interpolation_identifier', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_interpolation_identifier);
+      });
+      _ut.test('test_string_simple_single', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_single);
+      });
+      _ut.test('test_string_simple_unterminated_eof', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_unterminated_eof);
+      });
+      _ut.test('test_string_simple_unterminated_eol', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_unterminated_eol);
+      });
+      _ut.test('test_tilde', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_tilde);
+      });
+      _ut.test('test_tilde_slash', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_tilde_slash);
+      });
+      _ut.test('test_tilde_slash_eq', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_tilde_slash_eq);
+      });
+      _ut.test('test_unclosedPairInInterpolation', () {
+        final __test = new StringScannerTest();
+        runJUnitTest(__test, __test.test_unclosedPairInInterpolation);
+      });
+    });
+  }
+}
+abstract class AbstractScannerTest extends JUnitTestCase {
+  void test_ampersand() {
+    assertToken(TokenType.AMPERSAND, "&");
+  }
+  void test_ampersand_ampersand() {
+    assertToken(TokenType.AMPERSAND_AMPERSAND, "&&");
+  }
+  void test_ampersand_eq() {
+    assertToken(TokenType.AMPERSAND_EQ, "&=");
+  }
+  void test_at() {
+    assertToken(TokenType.AT, "@");
+  }
+  void test_backping() {
+    assertToken(TokenType.BACKPING, "`");
+  }
+  void test_backslash() {
+    assertToken(TokenType.BACKSLASH, "\\");
+  }
+  void test_bang() {
+    assertToken(TokenType.BANG, "!");
+  }
+  void test_bang_eq() {
+    assertToken(TokenType.BANG_EQ, "!=");
+  }
+  void test_bar() {
+    assertToken(TokenType.BAR, "|");
+  }
+  void test_bar_bar() {
+    assertToken(TokenType.BAR_BAR, "||");
+  }
+  void test_bar_eq() {
+    assertToken(TokenType.BAR_EQ, "|=");
+  }
+  void test_caret() {
+    assertToken(TokenType.CARET, "^");
+  }
+  void test_caret_eq() {
+    assertToken(TokenType.CARET_EQ, "^=");
+  }
+  void test_close_curly_bracket() {
+    assertToken(TokenType.CLOSE_CURLY_BRACKET, "}");
+  }
+  void test_close_paren() {
+    assertToken(TokenType.CLOSE_PAREN, ")");
+  }
+  void test_close_quare_bracket() {
+    assertToken(TokenType.CLOSE_SQUARE_BRACKET, "]");
+  }
+  void test_colon() {
+    assertToken(TokenType.COLON, ":");
+  }
+  void test_comma() {
+    assertToken(TokenType.COMMA, ",");
+  }
+  void test_comment_multi() {
+    assertComment(TokenType.MULTI_LINE_COMMENT, "/* comment */");
+  }
+  void test_comment_multi_unterminated() {
+    assertError(ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT, 3, "/* x");
+  }
+  void test_comment_nested() {
+    assertComment(TokenType.MULTI_LINE_COMMENT, "/* comment /* within a */ comment */");
+  }
+  void test_comment_single() {
+    assertComment(TokenType.SINGLE_LINE_COMMENT, "// comment");
+  }
+  void test_double_both_e() {
+    assertToken(TokenType.DOUBLE, "0.123e4");
+  }
+  void test_double_both_E() {
+    assertToken(TokenType.DOUBLE, "0.123E4");
+  }
+  void test_double_fraction() {
+    assertToken(TokenType.DOUBLE, ".123");
+  }
+  void test_double_fraction_d() {
+    assertToken(TokenType.DOUBLE, ".123d");
+  }
+  void test_double_fraction_D() {
+    assertToken(TokenType.DOUBLE, ".123D");
+  }
+  void test_double_fraction_e() {
+    assertToken(TokenType.DOUBLE, ".123e4");
+  }
+  void test_double_fraction_E() {
+    assertToken(TokenType.DOUBLE, ".123E4");
+  }
+  void test_double_fraction_ed() {
+    assertToken(TokenType.DOUBLE, ".123e4d");
+  }
+  void test_double_fraction_Ed() {
+    assertToken(TokenType.DOUBLE, ".123E4d");
+  }
+  void test_double_missingDigitInExponent() {
+    assertError(ScannerErrorCode.MISSING_DIGIT, 1, "1e");
+  }
+  void test_double_whole_d() {
+    assertToken(TokenType.DOUBLE, "12d");
+  }
+  void test_double_whole_D() {
+    assertToken(TokenType.DOUBLE, "12D");
+  }
+  void test_double_whole_e() {
+    assertToken(TokenType.DOUBLE, "12e4");
+  }
+  void test_double_whole_E() {
+    assertToken(TokenType.DOUBLE, "12E4");
+  }
+  void test_double_whole_ed() {
+    assertToken(TokenType.DOUBLE, "12e4d");
+  }
+  void test_double_whole_Ed() {
+    assertToken(TokenType.DOUBLE, "12E4d");
+  }
+  void test_eq() {
+    assertToken(TokenType.EQ, "=");
+  }
+  void test_eq_eq() {
+    assertToken(TokenType.EQ_EQ, "==");
+  }
+  void test_gt() {
+    assertToken(TokenType.GT, ">");
+  }
+  void test_gt_eq() {
+    assertToken(TokenType.GT_EQ, ">=");
+  }
+  void test_gt_gt() {
+    assertToken(TokenType.GT_GT, ">>");
+  }
+  void test_gt_gt_eq() {
+    assertToken(TokenType.GT_GT_EQ, ">>=");
+  }
+  void test_hash() {
+    assertToken(TokenType.HASH, "#");
+  }
+  void test_hexidecimal() {
+    assertToken(TokenType.HEXADECIMAL, "0x1A2B3C");
+  }
+  void test_hexidecimal_missingDigit() {
+    assertError(ScannerErrorCode.MISSING_HEX_DIGIT, 1, "0x");
+  }
+  void test_identifier() {
+    assertToken(TokenType.IDENTIFIER, "result");
+  }
+  void test_illegalChar() {
+    assertError(ScannerErrorCode.ILLEGAL_CHARACTER, 0, "\u0312");
+  }
+  void test_index() {
+    assertToken(TokenType.INDEX, "[]");
+  }
+  void test_index_eq() {
+    assertToken(TokenType.INDEX_EQ, "[]=");
+  }
+  void test_int() {
+    assertToken(TokenType.INT, "123");
+  }
+  void test_int_initialZero() {
+    assertToken(TokenType.INT, "0123");
+  }
+  void test_keyword_abstract() {
+    assertKeywordToken("abstract");
+  }
+  void test_keyword_as() {
+    assertKeywordToken("as");
+  }
+  void test_keyword_assert() {
+    assertKeywordToken("assert");
+  }
+  void test_keyword_break() {
+    assertKeywordToken("break");
+  }
+  void test_keyword_case() {
+    assertKeywordToken("case");
+  }
+  void test_keyword_catch() {
+    assertKeywordToken("catch");
+  }
+  void test_keyword_class() {
+    assertKeywordToken("class");
+  }
+  void test_keyword_const() {
+    assertKeywordToken("const");
+  }
+  void test_keyword_continue() {
+    assertKeywordToken("continue");
+  }
+  void test_keyword_default() {
+    assertKeywordToken("default");
+  }
+  void test_keyword_do() {
+    assertKeywordToken("do");
+  }
+  void test_keyword_dynamic() {
+    assertKeywordToken("dynamic");
+  }
+  void test_keyword_else() {
+    assertKeywordToken("else");
+  }
+  void test_keyword_export() {
+    assertKeywordToken("export");
+  }
+  void test_keyword_extends() {
+    assertKeywordToken("extends");
+  }
+  void test_keyword_factory() {
+    assertKeywordToken("factory");
+  }
+  void test_keyword_false() {
+    assertKeywordToken("false");
+  }
+  void test_keyword_final() {
+    assertKeywordToken("final");
+  }
+  void test_keyword_finally() {
+    assertKeywordToken("finally");
+  }
+  void test_keyword_for() {
+    assertKeywordToken("for");
+  }
+  void test_keyword_get() {
+    assertKeywordToken("get");
+  }
+  void test_keyword_if() {
+    assertKeywordToken("if");
+  }
+  void test_keyword_implements() {
+    assertKeywordToken("implements");
+  }
+  void test_keyword_import() {
+    assertKeywordToken("import");
+  }
+  void test_keyword_in() {
+    assertKeywordToken("in");
+  }
+  void test_keyword_is() {
+    assertKeywordToken("is");
+  }
+  void test_keyword_library() {
+    assertKeywordToken("library");
+  }
+  void test_keyword_new() {
+    assertKeywordToken("new");
+  }
+  void test_keyword_null() {
+    assertKeywordToken("null");
+  }
+  void test_keyword_operator() {
+    assertKeywordToken("operator");
+  }
+  void test_keyword_part() {
+    assertKeywordToken("part");
+  }
+  void test_keyword_return() {
+    assertKeywordToken("return");
+  }
+  void test_keyword_set() {
+    assertKeywordToken("set");
+  }
+  void test_keyword_static() {
+    assertKeywordToken("static");
+  }
+  void test_keyword_super() {
+    assertKeywordToken("super");
+  }
+  void test_keyword_switch() {
+    assertKeywordToken("switch");
+  }
+  void test_keyword_this() {
+    assertKeywordToken("this");
+  }
+  void test_keyword_throw() {
+    assertKeywordToken("throw");
+  }
+  void test_keyword_true() {
+    assertKeywordToken("true");
+  }
+  void test_keyword_try() {
+    assertKeywordToken("try");
+  }
+  void test_keyword_typedef() {
+    assertKeywordToken("typedef");
+  }
+  void test_keyword_var() {
+    assertKeywordToken("var");
+  }
+  void test_keyword_void() {
+    assertKeywordToken("void");
+  }
+  void test_keyword_while() {
+    assertKeywordToken("while");
+  }
+  void test_keyword_with() {
+    assertKeywordToken("with");
+  }
+  void test_lt() {
+    assertToken(TokenType.LT, "<");
+  }
+  void test_lt_eq() {
+    assertToken(TokenType.LT_EQ, "<=");
+  }
+  void test_lt_lt() {
+    assertToken(TokenType.LT_LT, "<<");
+  }
+  void test_lt_lt_eq() {
+    assertToken(TokenType.LT_LT_EQ, "<<=");
+  }
+  void test_minus() {
+    assertToken(TokenType.MINUS, "-");
+  }
+  void test_minus_eq() {
+    assertToken(TokenType.MINUS_EQ, "-=");
+  }
+  void test_minus_minus() {
+    assertToken(TokenType.MINUS_MINUS, "--");
+  }
+  void test_open_curly_bracket() {
+    assertToken(TokenType.OPEN_CURLY_BRACKET, "{");
+  }
+  void test_open_paren() {
+    assertToken(TokenType.OPEN_PAREN, "(");
+  }
+  void test_open_square_bracket() {
+    assertToken(TokenType.OPEN_SQUARE_BRACKET, "[");
+  }
+  void test_openSquareBracket() {
+    assertToken(TokenType.OPEN_SQUARE_BRACKET, "[");
+  }
+  void test_percent() {
+    assertToken(TokenType.PERCENT, "%");
+  }
+  void test_percent_eq() {
+    assertToken(TokenType.PERCENT_EQ, "%=");
+  }
+  void test_period() {
+    assertToken(TokenType.PERIOD, ".");
+  }
+  void test_period_period() {
+    assertToken(TokenType.PERIOD_PERIOD, "..");
+  }
+  void test_period_period_period() {
+    assertToken(TokenType.PERIOD_PERIOD_PERIOD, "...");
+  }
+  void test_periodAfterNumberNotIncluded_identifier() {
+    assertTokens("42.isEven()", [new StringToken(TokenType.INT, "42", 0), new Token(TokenType.PERIOD, 2), new StringToken(TokenType.IDENTIFIER, "isEven", 3), new Token(TokenType.OPEN_PAREN, 9), new Token(TokenType.CLOSE_PAREN, 10)]);
+  }
+  void test_periodAfterNumberNotIncluded_period() {
+    assertTokens("42..isEven()", [new StringToken(TokenType.INT, "42", 0), new Token(TokenType.PERIOD_PERIOD, 2), new StringToken(TokenType.IDENTIFIER, "isEven", 4), new Token(TokenType.OPEN_PAREN, 10), new Token(TokenType.CLOSE_PAREN, 11)]);
+  }
+  void test_plus() {
+    assertToken(TokenType.PLUS, "+");
+  }
+  void test_plus_eq() {
+    assertToken(TokenType.PLUS_EQ, "+=");
+  }
+  void test_plus_plus() {
+    assertToken(TokenType.PLUS_PLUS, "++");
+  }
+  void test_question() {
+    assertToken(TokenType.QUESTION, "?");
+  }
+  void test_scriptTag_withArgs() {
+    assertToken(TokenType.SCRIPT_TAG, "#!/bin/dart -debug");
+  }
+  void test_scriptTag_withoutSpace() {
+    assertToken(TokenType.SCRIPT_TAG, "#!/bin/dart");
+  }
+  void test_scriptTag_withSpace() {
+    assertToken(TokenType.SCRIPT_TAG, "#! /bin/dart");
+  }
+  void test_semicolon() {
+    assertToken(TokenType.SEMICOLON, ";");
+  }
+  void test_slash() {
+    assertToken(TokenType.SLASH, "/");
+  }
+  void test_slash_eq() {
+    assertToken(TokenType.SLASH_EQ, "/=");
+  }
+  void test_star() {
+    assertToken(TokenType.STAR, "*");
+  }
+  void test_star_eq() {
+    assertToken(TokenType.STAR_EQ, "*=");
+  }
+  void test_startAndEnd() {
+    Token token = scan2("a");
+    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);
+  }
+  void test_string_multi_double() {
+    assertToken(TokenType.STRING, "\"\"\"multi-line\nstring\"\"\"");
+  }
+  void test_string_multi_interpolation_block() {
+    assertTokens("\"Hello \${name}!\"", [new StringToken(TokenType.STRING, "\"Hello ", 0), new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 7), new StringToken(TokenType.IDENTIFIER, "name", 9), new Token(TokenType.CLOSE_CURLY_BRACKET, 13), new StringToken(TokenType.STRING, "!\"", 14)]);
+  }
+  void test_string_multi_interpolation_identifier() {
+    assertTokens("\"Hello \$name!\"", [new StringToken(TokenType.STRING, "\"Hello ", 0), new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 7), new StringToken(TokenType.IDENTIFIER, "name", 8), new StringToken(TokenType.STRING, "!\"", 12)]);
+  }
+  void test_string_multi_single() {
+    assertToken(TokenType.STRING, "'''string'''");
+  }
+  void test_string_multi_unterminated() {
+    assertError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 8, "'''string");
+  }
+  void test_string_raw_multi_double() {
+    assertToken(TokenType.STRING, "r\"\"\"string\"\"\"");
+  }
+  void test_string_raw_multi_single() {
+    assertToken(TokenType.STRING, "r'''string'''");
+  }
+  void test_string_raw_multi_unterminated() {
+    assertError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 9, "r'''string");
+  }
+  void test_string_raw_simple_double() {
+    assertToken(TokenType.STRING, "r\"string\"");
+  }
+  void test_string_raw_simple_single() {
+    assertToken(TokenType.STRING, "r'string'");
+  }
+  void test_string_raw_simple_unterminated_eof() {
+    assertError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 7, "r'string");
+  }
+  void test_string_raw_simple_unterminated_eol() {
+    assertError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 8, "r'string\n");
+  }
+  void test_string_simple_double() {
+    assertToken(TokenType.STRING, "\"string\"");
+  }
+  void test_string_simple_escapedDollar() {
+    assertToken(TokenType.STRING, "'a\\\$b'");
+  }
+  void test_string_simple_interpolation_block() {
+    assertTokens("'Hello \${name}!'", [new StringToken(TokenType.STRING, "'Hello ", 0), new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 7), new StringToken(TokenType.IDENTIFIER, "name", 9), new Token(TokenType.CLOSE_CURLY_BRACKET, 13), new StringToken(TokenType.STRING, "!'", 14)]);
+  }
+  void test_string_simple_interpolation_blockWithNestedMap() {
+    assertTokens("'a \${f({'b' : 'c'})} d'", [new StringToken(TokenType.STRING, "'a ", 0), new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 3), new StringToken(TokenType.IDENTIFIER, "f", 5), new Token(TokenType.OPEN_PAREN, 6), new Token(TokenType.OPEN_CURLY_BRACKET, 7), new StringToken(TokenType.STRING, "'b'", 8), new Token(TokenType.COLON, 12), new StringToken(TokenType.STRING, "'c'", 14), new Token(TokenType.CLOSE_CURLY_BRACKET, 17), new Token(TokenType.CLOSE_PAREN, 18), new Token(TokenType.CLOSE_CURLY_BRACKET, 19), new StringToken(TokenType.STRING, " d'", 20)]);
+  }
+  void test_string_simple_interpolation_firstAndLast() {
+    assertTokens("'\$greeting \$name'", [new StringToken(TokenType.STRING, "'", 0), new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 1), new StringToken(TokenType.IDENTIFIER, "greeting", 2), new StringToken(TokenType.STRING, " ", 10), new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 11), new StringToken(TokenType.IDENTIFIER, "name", 12), new StringToken(TokenType.STRING, "'", 16)]);
+  }
+  void test_string_simple_interpolation_identifier() {
+    assertTokens("'Hello \$name!'", [new StringToken(TokenType.STRING, "'Hello ", 0), new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 7), new StringToken(TokenType.IDENTIFIER, "name", 8), new StringToken(TokenType.STRING, "!'", 12)]);
+  }
+  void test_string_simple_single() {
+    assertToken(TokenType.STRING, "'string'");
+  }
+  void test_string_simple_unterminated_eof() {
+    assertError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 6, "'string");
+  }
+  void test_string_simple_unterminated_eol() {
+    assertError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 7, "'string\r");
+  }
+  void test_tilde() {
+    assertToken(TokenType.TILDE, "~");
+  }
+  void test_tilde_slash() {
+    assertToken(TokenType.TILDE_SLASH, "~/");
+  }
+  void test_tilde_slash_eq() {
+    assertToken(TokenType.TILDE_SLASH_EQ, "~/=");
+  }
+  void test_unclosedPairInInterpolation() {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    scan("'\${(}'", listener);
+  }
+  Token scan(String source, GatheringErrorListener listener);
+  void assertComment(TokenType commentType, String source) {
+    Token token = scan2(source);
+    JUnitTestCase.assertNotNull(token);
+    JUnitTestCase.assertEquals(TokenType.EOF, token.type);
+    Token comment = token.precedingComments;
+    JUnitTestCase.assertNotNull(comment);
+    JUnitTestCase.assertEquals(commentType, comment.type);
+    JUnitTestCase.assertEquals(0, comment.offset);
+    JUnitTestCase.assertEquals(source.length, comment.length);
+    JUnitTestCase.assertEquals(source, comment.lexeme);
+  }
+  /**
+   * Assert that scanning the given source produces an error with the given code.
+   * @param illegalCharacter
+   * @param i
+   * @param source the source to be scanned to produce the error
+   */
+  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])]);
+  }
+  /**
+   * Assert that when scanned the given source contains a single keyword token with the same lexeme
+   * as the original source.
+   * @param source the source to be scanned
+   */
+  void assertKeywordToken(String source) {
+    Token token = scan2(source);
+    JUnitTestCase.assertNotNull(token);
+    JUnitTestCase.assertEquals(TokenType.KEYWORD, token.type);
+    JUnitTestCase.assertEquals(0, token.offset);
+    JUnitTestCase.assertEquals(source.length, token.length);
+    JUnitTestCase.assertEquals(source, token.lexeme);
+    Object value3 = token.value();
+    JUnitTestCase.assertTrue(value3 is Keyword);
+    JUnitTestCase.assertEquals(source, (value3 as Keyword).syntax);
+    token = scan2(" ${source} ");
+    JUnitTestCase.assertNotNull(token);
+    JUnitTestCase.assertEquals(TokenType.KEYWORD, token.type);
+    JUnitTestCase.assertEquals(1, token.offset);
+    JUnitTestCase.assertEquals(source.length, token.length);
+    JUnitTestCase.assertEquals(source, token.lexeme);
+    value3 = token.value();
+    JUnitTestCase.assertTrue(value3 is Keyword);
+    JUnitTestCase.assertEquals(source, (value3 as Keyword).syntax);
+    JUnitTestCase.assertEquals(TokenType.EOF, token.next.type);
+  }
+  /**
+   * Assert that the token scanned from the given source has the expected type.
+   * @param expectedType the expected type of the token
+   * @param source the source to be scanned to produce the actual token
+   */
+  Token assertToken(TokenType expectedType, String source) {
+    Token originalToken = scan2(source);
+    JUnitTestCase.assertNotNull(originalToken);
+    JUnitTestCase.assertEquals(expectedType, originalToken.type);
+    JUnitTestCase.assertEquals(0, originalToken.offset);
+    JUnitTestCase.assertEquals(source.length, originalToken.length);
+    JUnitTestCase.assertEquals(source, originalToken.lexeme);
+    if (expectedType == TokenType.SCRIPT_TAG) {
+      return originalToken;
+    } else if (expectedType == TokenType.SINGLE_LINE_COMMENT) {
+      Token tokenWithSpaces = scan2(" ${source}");
+      JUnitTestCase.assertNotNull(tokenWithSpaces);
+      JUnitTestCase.assertEquals(expectedType, tokenWithSpaces.type);
+      JUnitTestCase.assertEquals(1, tokenWithSpaces.offset);
+      JUnitTestCase.assertEquals(source.length, tokenWithSpaces.length);
+      JUnitTestCase.assertEquals(source, tokenWithSpaces.lexeme);
+      return originalToken;
+    }
+    Token tokenWithSpaces = scan2(" ${source} ");
+    JUnitTestCase.assertNotNull(tokenWithSpaces);
+    JUnitTestCase.assertEquals(expectedType, tokenWithSpaces.type);
+    JUnitTestCase.assertEquals(1, tokenWithSpaces.offset);
+    JUnitTestCase.assertEquals(source.length, tokenWithSpaces.length);
+    JUnitTestCase.assertEquals(source, tokenWithSpaces.lexeme);
+    JUnitTestCase.assertEquals(TokenType.EOF, originalToken.next.type);
+    return originalToken;
+  }
+  /**
+   * Assert that when scanned the given source contains a sequence of tokens identical to the given
+   * tokens.
+   * @param source the source to be scanned
+   * @param expectedTokens the tokens that are expected to be in the source
+   */
+  void assertTokens(String source, List<Token> expectedTokens) {
+    Token token = scan2(source);
+    JUnitTestCase.assertNotNull(token);
+    for (int i = 0; i < expectedTokens.length; i++) {
+      Token expectedToken = expectedTokens[i];
+      JUnitTestCase.assertEqualsMsg("Wrong type for token ${i}", expectedToken.type, token.type);
+      JUnitTestCase.assertEqualsMsg("Wrong offset for token ${i}", expectedToken.offset, token.offset);
+      JUnitTestCase.assertEqualsMsg("Wrong length for token ${i}", expectedToken.length, token.length);
+      JUnitTestCase.assertEqualsMsg("Wrong lexeme for token ${i}", expectedToken.lexeme, token.lexeme);
+      token = token.next;
+      JUnitTestCase.assertNotNull(token);
+    }
+    JUnitTestCase.assertEquals(TokenType.EOF, token.type);
+  }
+  Token scan2(String source) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    Token token = scan(source, listener);
+    listener.assertNoErrors();
+    return token;
+  }
+}
+main() {
+  CharBufferScannerTest.dartSuite();
+  KeywordStateTest.dartSuite();
+  StringScannerTest.dartSuite();
+  TokenTypeTest.dartSuite();
+}
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/test/generated/test_support.dart b/pkg/analyzer-experimental/test/generated/test_support.dart
new file mode 100644
index 0000000..1037c15
--- /dev/null
+++ b/pkg/analyzer-experimental/test/generated/test_support.dart
@@ -0,0 +1,622 @@
+// 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.test_support;
+
+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:unittest/unittest.dart' as _ut;
+
+/**
+ * Instances of the class {@code GatheringErrorListener} implement an error listener that collects
+ * all of the errors passed to it for later examination.
+ */
+class GatheringErrorListener implements AnalysisErrorListener {
+  /**
+   * The source being parsed.
+   */
+  String _rawSource;
+  /**
+   * The source being parsed after inserting a marker at the beginning and end of the range of the
+   * most recent error.
+   */
+  String _markedSource;
+  /**
+   * A list containing the errors that were collected.
+   */
+  List<AnalysisError> _errors = new List<AnalysisError>();
+  /**
+   * A table mapping sources to the line information for the source.
+   */
+  Map<Source, LineInfo> _lineInfoMap = new Map<Source, LineInfo>();
+  /**
+   * An empty array of errors used when no errors are expected.
+   */
+  static List<AnalysisError> _NO_ERRORS = new List<AnalysisError>.fixedLength(0);
+  /**
+   * Initialize a newly created error listener to collect errors.
+   */
+  GatheringErrorListener() : super() {
+    _jtd_constructor_234_impl();
+  }
+  _jtd_constructor_234_impl() {
+  }
+  /**
+   * Initialize a newly created error listener to collect errors.
+   */
+  GatheringErrorListener.con1(String rawSource) {
+    _jtd_constructor_235_impl(rawSource);
+  }
+  _jtd_constructor_235_impl(String rawSource) {
+    this._rawSource = rawSource;
+    this._markedSource = rawSource;
+  }
+  /**
+   * Assert that the number of errors that have been gathered matches the number of errors that are
+   * given and that they have the expected error codes and locations. The order in which the errors
+   * were gathered is ignored.
+   * @param errorCodes the errors that should have been gathered
+   * @throws AssertionFailedError if a different number of errors have been gathered than were
+   * expected or if they do not have the same codes and locations
+   */
+  void assertErrors(List<AnalysisError> expectedErrors) {
+    if (_errors.length != expectedErrors.length) {
+      fail(expectedErrors);
+    }
+    List<AnalysisError> remainingErrors = new List<AnalysisError>();
+    for (AnalysisError error in expectedErrors) {
+      remainingErrors.add(error);
+    }
+    for (AnalysisError error in _errors) {
+      if (!foundAndRemoved(remainingErrors, error)) {
+        fail(expectedErrors);
+      }
+    }
+  }
+  /**
+   * Assert that the number of errors that have been gathered matches the number of errors that are
+   * given and that they have the expected error codes. The order in which the errors were gathered
+   * is ignored.
+   * @param expectedErrorCodes the error codes of the errors that should have been gathered
+   * @throws AssertionFailedError if a different number of errors have been gathered than were
+   * expected
+   */
+  void assertErrors2(List<ErrorCode> expectedErrorCodes) {
+    StringBuffer builder = new StringBuffer();
+    Map<ErrorCode, int> expectedCounts = new Map<ErrorCode, int>();
+    for (ErrorCode code in expectedErrorCodes) {
+      int count = expectedCounts[code];
+      if (count == null) {
+        count = 1;
+      } else {
+        count = count + 1;
+      }
+      expectedCounts[code] = count;
+    }
+    Map<ErrorCode, List<AnalysisError>> errorsByCode = new Map<ErrorCode, List<AnalysisError>>();
+    for (AnalysisError error in _errors) {
+      ErrorCode code = error.errorCode;
+      List<AnalysisError> list = errorsByCode[code];
+      if (list == null) {
+        list = new List<AnalysisError>();
+        errorsByCode[code] = list;
+      }
+      list.add(error);
+    }
+    for (MapEntry<ErrorCode, int> entry in getMapEntrySet(expectedCounts)) {
+      ErrorCode code = entry.getKey();
+      int expectedCount = entry.getValue();
+      int actualCount;
+      List<AnalysisError> list = errorsByCode.remove(code);
+      if (list == null) {
+        actualCount = 0;
+      } else {
+        actualCount = list.length;
+      }
+      if (actualCount != expectedCount) {
+        if (builder.length == 0) {
+          builder.add("Expected ");
+        } else {
+          builder.add("; ");
+        }
+        builder.add(expectedCount);
+        builder.add(" errors of type ");
+        builder.add(code);
+        builder.add(", found ");
+        builder.add(actualCount);
+      }
+    }
+    for (MapEntry<ErrorCode, List<AnalysisError>> entry in getMapEntrySet(errorsByCode)) {
+      ErrorCode code = entry.getKey();
+      List<AnalysisError> actualErrors = entry.getValue();
+      int actualCount = actualErrors.length;
+      if (builder.length == 0) {
+        builder.add("Expected ");
+      } else {
+        builder.add("; ");
+      }
+      builder.add("0 errors of type ");
+      builder.add(code);
+      builder.add(", found ");
+      builder.add(actualCount);
+      builder.add(" (");
+      for (int i = 0; i < actualErrors.length; i++) {
+        AnalysisError error = actualErrors[i];
+        if (i > 0) {
+          builder.add(", ");
+        }
+        builder.add(error.offset);
+      }
+      builder.add(")");
+    }
+    if (builder.length > 0) {
+      JUnitTestCase.fail(builder.toString());
+    }
+  }
+  /**
+   * Assert that the number of errors that have been gathered matches the number of severities that
+   * are given and that there are the same number of errors and warnings as specified by the
+   * argument. The order in which the errors were gathered is ignored.
+   * @param expectedSeverities the severities of the errors that should have been gathered
+   * @throws AssertionFailedError if a different number of errors have been gathered than were
+   * expected
+   */
+  void assertErrors3(List<ErrorSeverity> expectedSeverities) {
+    int expectedErrorCount = 0;
+    int expectedWarningCount = 0;
+    for (ErrorSeverity severity in expectedSeverities) {
+      if (severity == ErrorSeverity.ERROR) {
+        expectedErrorCount++;
+      } else {
+        expectedWarningCount++;
+      }
+    }
+    int actualErrorCount = 0;
+    int actualWarningCount = 0;
+    for (AnalysisError error in _errors) {
+      if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) {
+        actualErrorCount++;
+      } else {
+        actualWarningCount++;
+      }
+    }
+    if (expectedErrorCount != actualErrorCount || expectedWarningCount != actualWarningCount) {
+      JUnitTestCase.fail("Expected ${expectedErrorCount} errors and ${expectedWarningCount} warnings, found ${actualErrorCount} errors and ${actualWarningCount} warnings");
+    }
+  }
+  /**
+   * Assert that no errors have been gathered.
+   * @throws AssertionFailedError if any errors have been gathered
+   */
+  void assertNoErrors() {
+    assertErrors(GatheringErrorListener._NO_ERRORS);
+  }
+  /**
+   * Return the errors that were collected.
+   * @return the errors that were collected
+   */
+  List<AnalysisError> get errors => _errors;
+  /**
+   * Return {@code true} if an error with the given error code has been gathered.
+   * @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) {
+    for (AnalysisError error in _errors) {
+      if (error.errorCode == errorCode) {
+        return true;
+      }
+    }
+    return false;
+  }
+  void onError(AnalysisError error) {
+    if (_rawSource != null) {
+      int left = error.offset;
+      int right = left + error.length - 1;
+      _markedSource = "${_rawSource.substring(0, left)}^${_rawSource.substring(left, right)}^${_rawSource.substring(right)}";
+    }
+    _errors.add(error);
+  }
+  /**
+   * Set the line information associated with the given source to the given information.
+   * @param source the source with which the line information is associated
+   * @param lineStarts the line start information to be associated with the source
+   */
+  void setLineInfo(Source source, List<int> lineStarts) {
+    _lineInfoMap[source] = new LineInfo(lineStarts);
+  }
+  /**
+   * Set the line information associated with the given source to the given information.
+   * @param source the source with which the line information is associated
+   * @param lineInfo the line information to be associated with the source
+   */
+  void setLineInfo2(Source source, LineInfo lineInfo) {
+    _lineInfoMap[source] = lineInfo;
+  }
+  /**
+   * Return {@code true} if the two errors are equivalent.
+   * @param firstError the first error being compared
+   * @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);
+  /**
+   * Return {@code true} if the two sources are equivalent.
+   * @param firstSource the first source being compared
+   * @param secondSource the second source being compared
+   * @return {@code true} if the two sources are equivalent
+   */
+  bool equals3(Source firstSource, Source secondSource) {
+    if (firstSource == null) {
+      return secondSource == null;
+    } else if (secondSource == null) {
+      return false;
+    }
+    return firstSource == secondSource;
+  }
+  /**
+   * Assert that the number of errors that have been gathered matches the number of errors that are
+   * given and that they have the expected error codes. The order in which the errors were gathered
+   * is ignored.
+   * @param errorCodes the errors that should have been gathered
+   * @throws AssertionFailedError with
+   */
+  void fail(List<AnalysisError> expectedErrors) {
+    PrintStringWriter writer = new PrintStringWriter();
+    writer.print("Expected ");
+    writer.print(expectedErrors.length);
+    writer.print(" errors:");
+    for (AnalysisError error in expectedErrors) {
+      Source source5 = error.source;
+      LineInfo lineInfo = _lineInfoMap[source5];
+      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]);
+      } 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.println();
+    writer.print("found ");
+    writer.print(_errors.length);
+    writer.print(" errors:");
+    for (AnalysisError error in _errors) {
+      Source source6 = error.source;
+      LineInfo lineInfo = _lineInfoMap[source6];
+      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]);
+      } 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]);
+      }
+    }
+    JUnitTestCase.fail(writer.toString());
+  }
+  /**
+   * Search through the given list of errors for an error that is equal to the target error. If one
+   * is found, remove it from the list and return {@code true}, otherwise return {@code false}without modifying the list.
+   * @param errors the errors through which we are searching
+   * @param targetError the error being searched for
+   * @return {@code true} if the error is found and removed from the list
+   */
+  bool foundAndRemoved(List<AnalysisError> errors, AnalysisError targetError) {
+    for (AnalysisError error in errors) {
+      if (equals(error, targetError)) {
+        errors.remove(error);
+        return true;
+      }
+    }
+    return true;
+  }
+}
+/**
+ * The class {@code EngineTestCase} defines utility methods for making assertions.
+ */
+class EngineTestCase extends JUnitTestCase {
+  static int _PRINT_RANGE = 6;
+  /**
+   * Assert that the tokens in the actual stream of tokens have the same types and lexemes as the
+   * tokens in the expected stream of tokens. Note that this does not assert anything about the
+   * offsets of the tokens (although the lengths will be equal).
+   * @param expectedStream the head of the stream of tokens that were expected
+   * @param actualStream the head of the stream of tokens that were actually found
+   * @throws AssertionFailedError if the two streams of tokens are not the same
+   */
+  static void assertAllMatch(Token expectedStream, Token actualStream) {
+    Token left = expectedStream;
+    Token right = actualStream;
+    while (left.type != TokenType.EOF && right.type != TokenType.EOF) {
+      assertMatches(left, right);
+      left = left.next;
+      right = right.next;
+    }
+  }
+  /**
+   * Assert that the array of actual values contain exactly the same values as those in the array of
+   * expected value, with the exception that the order of the elements is not required to be the
+   * same.
+   * @param expectedValues the values that are expected to be found
+   * @param actualValues the actual values that are being compared against the expected values
+   */
+  static void assertEqualsIgnoreOrder(List<Object> expectedValues, List<Object> actualValues) {
+    JUnitTestCase.assertNotNull(actualValues);
+    int expectedLength = expectedValues.length;
+    JUnitTestCase.assertEquals(expectedLength, actualValues.length);
+    List<bool> found = new List<bool>.fixedLength(expectedLength);
+    for (int i = 0; i < expectedLength; i++) {
+      found[i] = false;
+    }
+    for (Object actualValue in actualValues) {
+      bool wasExpected = false;
+      for (int i = 0; i < expectedLength; i++) {
+        if (!found[i] && expectedValues[i] == actualValue) {
+          found[i] = true;
+          wasExpected = true;
+          break;
+        }
+      }
+      if (!wasExpected) {
+        JUnitTestCase.fail("The actual value ${actualValue} was not expected");
+      }
+    }
+  }
+  /**
+   * Assert that a given String is equal to an expected value.
+   * @param expected the expected String value
+   * @param actual the actual String value
+   */
+  static void assertEqualString(String expected, String actual) {
+    if (actual == null || expected == null) {
+      if (actual == expected) {
+        return;
+      }
+      if (actual == null) {
+        JUnitTestCase.assertTrueMsg("Content not as expected: is 'null' expected: ${expected}", false);
+      } else {
+        JUnitTestCase.assertTrueMsg("Content not as expected: expected 'null' is: ${actual}", false);
+      }
+    }
+    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);
+      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);
+    }
+  }
+  /**
+   * Assert that the given list is non-{@code null} and has exactly expected elements.
+   * @param list the list being tested
+   * @param expectedElements the expected elements
+   * @throws AssertionFailedError if the list is {@code null} or does not have the expected elements
+   */
+  static void assertExactElements(List<Object> list, List<Object> expectedElements) {
+    int expectedSize = expectedElements.length;
+    if (list == null) {
+      JUnitTestCase.fail("Expected list of size ${expectedSize}; found null");
+    }
+    if (list.length != expectedSize) {
+      JUnitTestCase.fail("Expected list of size ${expectedSize}; contained ${list.length} elements");
+    }
+    for (int i = 0; i < expectedElements.length; i++) {
+      Object element = list[i];
+      Object expectedElement = expectedElements[i];
+      if (!element == expectedElement) {
+        JUnitTestCase.fail("Expected ${expectedElement} at [${i}]; found ${element}");
+      }
+    }
+  }
+  /**
+   * Assert that the given array is non-{@code null} and has exactly expected elements.
+   * @param array the array being tested
+   * @param expectedElements the expected elements
+   * @throws AssertionFailedError if the array is {@code null} or does not have the expected
+   * elements
+   */
+  static void assertExactElements2(List<Object> array, List<Object> expectedElements) {
+    int expectedSize = expectedElements.length;
+    if (array == null) {
+      JUnitTestCase.fail("Expected array of size ${expectedSize}; found null");
+    }
+    if (array.length != expectedSize) {
+      JUnitTestCase.fail("Expected array of size ${expectedSize}; contained ${array.length} elements");
+    }
+    for (int i = 0; i < expectedElements.length; i++) {
+      Object element = array[0];
+      Object expectedElement = expectedElements[i];
+      if (!element == expectedElement) {
+        JUnitTestCase.fail("Expected ${expectedElement} at [${i}]; found ${element}");
+      }
+    }
+  }
+  /**
+   * Assert that the given list is non-{@code null} and has exactly expected elements.
+   * @param set the list being tested
+   * @param expectedElements the expected elements
+   * @throws AssertionFailedError if the list is {@code null} or does not have the expected elements
+   */
+  static void assertExactElements3(Set<Object> set, List<Object> expectedElements) {
+    int expectedSize = expectedElements.length;
+    if (set == null) {
+      JUnitTestCase.fail("Expected list of size ${expectedSize}; found null");
+    }
+    if (set.length != expectedSize) {
+      JUnitTestCase.fail("Expected list of size ${expectedSize}; contained ${set.length} elements");
+    }
+    for (int i = 0; i < expectedElements.length; i++) {
+      Object expectedElement = expectedElements[i];
+      if (!set.contains(expectedElement)) {
+        JUnitTestCase.fail("Expected ${expectedElement} in set${set}");
+      }
+    }
+  }
+  /**
+   * Assert that the given object is an instance of the expected class.
+   * @param expectedClass the class that the object is expected to be an instance of
+   * @param object the object being tested
+   * @return the object that was being tested
+   * @throws Exception if the object is not an instance of the expected class
+   */
+  static Object assertInstanceOf(Type expectedClass, Object object) {
+    if (!isInstanceOf(object, expectedClass)) {
+      JUnitTestCase.fail("Expected instance of ${expectedClass.toString()}, found ${(object == null ? "null" : object.runtimeType.toString())}");
+    }
+    return object as Object;
+  }
+  /**
+   * Assert that the given array is non-{@code null} and has the expected number of elements.
+   * @param expectedLength the expected number of elements
+   * @param array the array being tested
+   * @throws AssertionFailedError if the array is {@code null} or does not have the expected number
+   * of elements
+   */
+  static void assertLength(int expectedLength, List<Object> array) {
+    if (array == null) {
+      JUnitTestCase.fail("Expected array of length ${expectedLength}; found null");
+    } else if (array.length != expectedLength) {
+      JUnitTestCase.fail("Expected array of length ${expectedLength}; contained ${array.length} elements");
+    }
+  }
+  /**
+   * Assert that the actual token has the same type and lexeme as the expected token. Note that this
+   * does not assert anything about the offsets of the tokens (although the lengths will be equal).
+   * @param expectedToken the token that was expected
+   * @param actualToken the token that was found
+   * @throws AssertionFailedError if the two tokens are not the same
+   */
+  static void assertMatches(Token expectedToken, Token actualToken) {
+    JUnitTestCase.assertEquals(expectedToken.type, actualToken.type);
+    if (expectedToken is KeywordToken) {
+      assertInstanceOf(KeywordToken, actualToken);
+      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);
+    }
+  }
+  /**
+   * Assert that the given list is non-{@code null} and has the expected number of elements.
+   * @param expectedSize the expected number of elements
+   * @param list the list being tested
+   * @throws AssertionFailedError if the list is {@code null} or does not have the expected number
+   * of elements
+   */
+  static void assertSize(int expectedSize, List<Object> list) {
+    if (list == null) {
+      JUnitTestCase.fail("Expected list of size ${expectedSize}; found null");
+    } else if (list.length != expectedSize) {
+      JUnitTestCase.fail("Expected list of size ${expectedSize}; contained ${list.length} elements");
+    }
+  }
+  /**
+   * Assert that the given map is non-{@code null} and has the expected number of elements.
+   * @param expectedSize the expected number of elements
+   * @param map the map being tested
+   * @throws AssertionFailedError if the map is {@code null} or does not have the expected number of
+   * elements
+   */
+  static void assertSize2(int expectedSize, Map<Object, Object> map) {
+    if (map == null) {
+      JUnitTestCase.fail("Expected map of size ${expectedSize}; found null");
+    } else if (map.length != expectedSize) {
+      JUnitTestCase.fail("Expected map of size ${expectedSize}; contained ${map.length} elements");
+    }
+  }
+  /**
+   * Convert the given array of lines into a single source string.
+   * @param lines the lines to be merged into a single source string
+   * @return the source string composed of the given lines
+   */
+  static String createSource(List<String> lines) {
+    PrintStringWriter writer = new PrintStringWriter();
+    for (String line in lines) {
+      writer.printlnObject(line);
+    }
+    return writer.toString();
+  }
+  /**
+   * Calculate the offset where the given strings differ.
+   * @param str1 the first String to compare
+   * @param str2 the second String to compare
+   * @return the offset at which the strings differ (or <code>-1</code> if they do not)
+   */
+  static int getDiffPos(String str1, String str2) {
+    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)) {
+        diffPos = i;
+        break;
+      }
+    }
+    if (diffPos == -1 && str1.length != str2.length) {
+      diffPos = len1;
+    }
+    return diffPos;
+  }
+  static dartSuite() {
+    _ut.group('EngineTestCase', () {
+    });
+  }
+}
+main() {
+}
+
+class TestSource implements Source {
+  bool operator ==(Object object) {
+    return this == object;
+  }
+  void getContents(Source_ContentReceiver receiver) {
+    throw new UnsupportedOperationException();
+  }
+  String get fullName {
+    throw new UnsupportedOperationException();
+  }
+  String get shortName {
+    throw new UnsupportedOperationException();
+  }
+  bool isInSystemLibrary() {
+    throw new UnsupportedOperationException();
+  }
+  Source resolve(String uri) {
+    throw new UnsupportedOperationException();
+  }
+}
+
+/**
+ * Wrapper around [Function] which should be called with [target] and [arguments].
+ */
+class MethodTrampoline {
+  int parameterCount;
+  Function trampoline;
+  MethodTrampoline(this.parameterCount, this.trampoline);
+  Object invoke(target, List arguments) {
+    if (arguments.length != parameterCount) {
+      throw new IllegalArgumentException("${arguments.length} != $parameterCount");
+    }
+    switch (parameterCount) {
+      case 0:
+        return trampoline(target);
+      case 1:
+        return trampoline(target, arguments[0]);
+      case 2:
+        return trampoline(target, arguments[0], arguments[1]);
+      case 3:
+        return trampoline(target, arguments[0], arguments[1], arguments[2]);
+      case 4:
+        return trampoline(target, arguments[0], arguments[1], arguments[2], arguments[3]);
+      default:
+        throw new IllegalArgumentException("Not implemented for > 4 arguments");
+    }
+  }
+}
diff --git a/pkg/http/lib/src/byte_stream.dart b/pkg/http/lib/src/byte_stream.dart
index 3de17ef..3ef0b6e 100644
--- a/pkg/http/lib/src/byte_stream.dart
+++ b/pkg/http/lib/src/byte_stream.dart
@@ -33,4 +33,7 @@
   /// [encoding], which defaults to `Encoding.UTF_8`.
   Future<String> bytesToString([Encoding encoding=Encoding.UTF_8]) =>
       toBytes().then((bytes) => decodeString(bytes, encoding));
+
+  Stream<String> toStringStream([Encoding encoding=Encoding.UTF_8]) =>
+      wrapStream(mappedBy((bytes) => decodeString(bytes, encoding)));
 }
diff --git a/pkg/http/lib/src/utils.dart b/pkg/http/lib/src/utils.dart
index c61733e..a70e937 100644
--- a/pkg/http/lib/src/utils.dart
+++ b/pkg/http/lib/src/utils.dart
@@ -309,3 +309,16 @@
   }
   return nextElement(null);
 }
+
+// TODO(nweiz): remove this when issue 8310 is fixed.
+/// Returns a [Stream] identical to [stream], but piped through a new
+/// [StreamController]. This exists to work around issue 8310.
+Stream wrapStream(Stream stream) {
+  var controller = stream.isBroadcast
+      ? new StreamController.broadcast()
+      : new StreamController();
+  stream.listen(controller.add,
+      onError: (e) => controller.signalError(e),
+      onDone: controller.close);
+  return controller.stream;
+}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index e621a2b..9f94f23 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -27,6 +27,8 @@
 intl/test/date_time_format_file_odd_test: Skip
 intl/test/find_default_locale_standalone_test: Skip
 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.
 
 [ $runtime == opera && $compiler == dart2js ]
 intl/test/find_default_locale_browser_test: Fail
@@ -51,6 +53,8 @@
 intl/test/intl_message_test: Skip
 intl/test/intl_message_basic_example_test: Skip
 serialization/test/serialization_test: Skip
+analyzer-experimental/test/generated/parser_test: Skip
+analyzer-experimental/test/generated/scanner_test: Skip
 
 [ $compiler == dartc ]
 unittest/test/mock_regexp_negative_test: Fail
diff --git a/pkg/unittest/lib/mock.dart b/pkg/unittest/lib/mock.dart
index ce65249..730e4ff 100644
--- a/pkg/unittest/lib/mock.dart
+++ b/pkg/unittest/lib/mock.dart
@@ -24,6 +24,9 @@
  * [thenCall] and [alwaysCall] allow you to proxy mocked methods, chaining
  * to some other implementation. This provides a way to implement 'spies'.
  *
+ * For getters and setters, use "get foo" and "set foo"-style arguments
+ * to [callsTo].
+ *
  * You can disable logging for a particular [Behavior] easily:
  *
  *     m.when(callsTo('bar')).logging = false;
@@ -269,6 +272,10 @@
  * Returns a [CallMatcher] for the specified signature. [method] can be
  * null to match anything, or a literal [String], a predicate [Function],
  * or a [Matcher]. The various arguments can be scalar values or [Matcher]s.
+ * To match getters and setters, use "get " and "set " prefixes on the names.
+ * For example, for a property "foo", you could use "get foo" and "set foo"
+ * as literal string arguments to callsTo to match the getter and setter
+ * of "foo".
  */
 CallMatcher callsTo([method,
                      arg0 = _noArg,
@@ -1286,9 +1293,12 @@
     var args = invocation.positionalArguments;
     if (invocation.isGetter) {
       method = 'get $method';
-    } else if (method.startsWith('get:')) {
-      // TODO(gram): Remove this when VM handles the isGetter version above.
-      method = 'get ${method.substring(4)}';
+    } else if (invocation.isSetter) {
+      method = 'set $method';
+      // Remove the trailing '='.
+      if (method[method.length-1] == '=') {
+        method = method.substring(0, method.length - 1);
+      }
     }
     bool matchedMethodName = false;
     MatchState matchState = new MatchState();
diff --git a/pkg/unittest/lib/src/collection_matchers.dart b/pkg/unittest/lib/src/collection_matchers.dart
index b261226..80ac428 100644
--- a/pkg/unittest/lib/src/collection_matchers.dart
+++ b/pkg/unittest/lib/src/collection_matchers.dart
@@ -2,13 +2,12 @@
 // 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 matcher;
+
 /**
  * Returns a matcher which matches [Collection]s in which all elements
  * match the given [matcher].
  */
-
-part of matcher;
-
 Matcher everyElement(matcher) => new _EveryElement(wrapMatcher(matcher));
 
 class _EveryElement extends _CollectionMatcher {
diff --git a/pkg/unittest/lib/src/description.dart b/pkg/unittest/lib/src/description.dart
index d851d33..f566d32 100644
--- a/pkg/unittest/lib/src/description.dart
+++ b/pkg/unittest/lib/src/description.dart
@@ -1,14 +1,14 @@
 // 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 matcher;
+
 /**
  * The default implementation of IDescription. This should rarely need
  * substitution, although conceivably it is a place where other languages
  * could be supported.
  */
-
-part of matcher;
-
 class StringDescription implements Description {
   var _out;
 
diff --git a/pkg/unittest/lib/src/future_matchers.dart b/pkg/unittest/lib/src/future_matchers.dart
index b04c07a..77ba8bf 100644
--- a/pkg/unittest/lib/src/future_matchers.dart
+++ b/pkg/unittest/lib/src/future_matchers.dart
@@ -2,6 +2,8 @@
 // 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 matcher;
+
 /**
  * Matches a [Future] that completes successfully with a value. Note that this
  * creates an asynchronous expectation. The call to `expect()` that includes
@@ -11,9 +13,6 @@
  * To test that a Future completes with an exception, you can use [throws] and
  * [throwsA].
  */
-
-part of matcher;
-
 Matcher completes = const _Completes(null);
 
 /**
diff --git a/pkg/unittest/lib/src/interfaces.dart b/pkg/unittest/lib/src/interfaces.dart
index 3757f40..960cfbf 100644
--- a/pkg/unittest/lib/src/interfaces.dart
+++ b/pkg/unittest/lib/src/interfaces.dart
@@ -2,6 +2,8 @@
 // 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 matcher;
+
 // To decouple the reporting of errors, and allow for extensibility of
 // matchers, we make use of some interfaces.
 
@@ -13,9 +15,6 @@
  * is replaced it may be desirable to replace the [stringDescription]
  * error formatter with another.
  */
-
-part of matcher;
-
 typedef String ErrorFormatter(actual, Matcher matcher, String reason,
     MatchState matchState, bool verbose);
 
diff --git a/pkg/unittest/lib/src/map_matchers.dart b/pkg/unittest/lib/src/map_matchers.dart
index 4c1e572..eccc4ec 100644
--- a/pkg/unittest/lib/src/map_matchers.dart
+++ b/pkg/unittest/lib/src/map_matchers.dart
@@ -2,12 +2,11 @@
 // 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 matcher;
+
 /**
  * Returns a matcher which matches maps containing the given [value].
  */
-
-part of matcher;
-
 Matcher containsValue(value) => new _ContainsValue(value);
 
 class _ContainsValue extends BaseMatcher {
diff --git a/pkg/unittest/lib/src/numeric_matchers.dart b/pkg/unittest/lib/src/numeric_matchers.dart
index e1f1adf..e5dd7ef 100644
--- a/pkg/unittest/lib/src/numeric_matchers.dart
+++ b/pkg/unittest/lib/src/numeric_matchers.dart
@@ -2,13 +2,12 @@
 // 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 matcher;
+
 /**
  * Returns a matcher which matches if the match argument is greater
  * than the given [value].
  */
-
-part of matcher;
-
 Matcher greaterThan(value) =>
   new _OrderingComparison(value, false, false, true, 'a value greater than');
 
diff --git a/pkg/unittest/lib/src/string_matchers.dart b/pkg/unittest/lib/src/string_matchers.dart
index 8409f53..7f04a0c 100644
--- a/pkg/unittest/lib/src/string_matchers.dart
+++ b/pkg/unittest/lib/src/string_matchers.dart
@@ -2,13 +2,12 @@
 // 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 matcher;
+
 /**
  * Returns a matcher which matches if the match argument is a string and
  * is equal to [value] when compared case-insensitively.
  */
-
-part of matcher;
-
 Matcher equalsIgnoringCase(String value) => new _IsEqualIgnoringCase(value);
 
 class _IsEqualIgnoringCase extends _StringMatcher {
diff --git a/pkg/unittest/lib/src/test_case.dart b/pkg/unittest/lib/src/test_case.dart
index d791d37..b21f1af 100644
--- a/pkg/unittest/lib/src/test_case.dart
+++ b/pkg/unittest/lib/src/test_case.dart
@@ -2,15 +2,14 @@
 // 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 unittest;
+
 /**
  * testcase.dart: this file is sourced by unittest.dart. It defines [TestCase]
  * and assumes unittest defines the type [TestFunction].
  */
 
 /** Summarizes information about a single test case. */
-
-part of unittest;
-
 class TestCase {
   /** Identifier for this test. */
   final int id;
diff --git a/pkg/unittest/test/mock_test.dart b/pkg/unittest/test/mock_test.dart
index 181a08a..0a8033f 100644
--- a/pkg/unittest/test/mock_test.dart
+++ b/pkg/unittest/test/mock_test.dart
@@ -63,6 +63,21 @@
     expect(s, 'ACDEB');
   });
 
+  test('Mocking: getters/setters', () {
+    var m = new Mock();
+    var x = 0;
+    m.when(callsTo('get foo')).alwaysReturn(3);
+    m.when(callsTo('set foo')).alwaysCall((v) { x = v; });
+    m.when(callsTo('get bar')).alwaysReturn(5);
+    m.when(callsTo('set bar')).alwaysCall((v) { x = 2 * v; });
+    expect(m.foo, 3);
+    expect(m.bar, 5);
+    m.foo = 10;
+    expect(x, 10);
+    m.bar = 8;
+    expect(x, 16);
+  });
+
   test('Mocking: Mock List', () {
     var l = new MockList();
     l.when(callsTo('get length')).thenReturn(1);
diff --git a/runtime/embedders/openglui/android/android_graphics_handler.cc b/runtime/embedders/openglui/android/android_graphics_handler.cc
index 3c694a7..e96febe 100644
--- a/runtime/embedders/openglui/android/android_graphics_handler.cc
+++ b/runtime/embedders/openglui/android/android_graphics_handler.cc
@@ -6,7 +6,7 @@
 #include "embedders/openglui/common/log.h"
 
 AndroidGraphicsHandler::AndroidGraphicsHandler(android_app* application)
-    : GLGraphicsHandler(),
+    : GraphicsHandler(),
       application_(application),
       display_(EGL_NO_DISPLAY),
       surface_(EGL_NO_SURFACE),
@@ -32,7 +32,7 @@
       LOGI("eglChooseConfig");
       if (eglChooseConfig(display_, attributes, &config, 1, &numConfigs) &&
           numConfigs > 0) {
-        LOGI("eglGetConfigAttrib");
+        LOGI("eglGetConfigAttrib returned %d configs\n", numConfigs);
         if (eglGetConfigAttrib(display_, config,
                                EGL_NATIVE_VISUAL_ID, &format)) {
           ANativeWindow_setBuffersGeometry(application_->window, 0, 0, format);
@@ -48,8 +48,12 @@
                   width_ > 0 &&
                   eglQuerySurface(display_, surface_, EGL_HEIGHT, &height_) &&
                   height_ > 0) {
+                LOGI("Got dimensions %d x %d\n", width_, height_);
                 SetViewport(0, 0, width_, height_);
-                return 0;
+                LOGI("GL version %s\n", glGetString(GL_VERSION));
+                LOGI("GLSL version: %s\n",
+                    glGetString(GL_SHADING_LANGUAGE_VERSION));
+                return GraphicsHandler::Start();
               }
             }
           }
@@ -64,6 +68,7 @@
 
 void AndroidGraphicsHandler::Stop() {
   LOGI("Stopping graphics");
+  GraphicsHandler::Stop();
   if (display_ != EGL_NO_DISPLAY) {
     eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
     if (context_ != EGL_NO_CONTEXT) {
diff --git a/runtime/embedders/openglui/android/android_graphics_handler.h b/runtime/embedders/openglui/android/android_graphics_handler.h
index 9684688..6849ac3 100644
--- a/runtime/embedders/openglui/android/android_graphics_handler.h
+++ b/runtime/embedders/openglui/android/android_graphics_handler.h
@@ -6,9 +6,9 @@
 #define EMBEDDERS_OPENGLUI_ANDROID_ANDROID_GRAPHICS_HANDLER_H_
 
 #include <android_native_app_glue.h>
-#include "embedders/openglui/common/gl_graphics_handler.h"
+#include "embedders/openglui/common/graphics_handler.h"
 
-class AndroidGraphicsHandler : public GLGraphicsHandler {
+class AndroidGraphicsHandler : public GraphicsHandler {
   public:
     explicit AndroidGraphicsHandler(android_app* application);
 
diff --git a/runtime/embedders/openglui/android/eventloop.cc b/runtime/embedders/openglui/android/eventloop.cc
index db92107..2d3bf6c 100644
--- a/runtime/embedders/openglui/android/eventloop.cc
+++ b/runtime/embedders/openglui/android/eventloop.cc
@@ -27,9 +27,11 @@
   input_handler_ = input_handler;
   LOGI("Starting event loop");
   while (true) {
-    // If not enabled, block on events. If enabled, don't block
-    // so we can do useful work in onStep.
-    while ((result = ALooper_pollAll(enabled_ ? 0 : -1,
+    // If not enabled, block indefinitely on events. If enabled, block
+    // briefly so we can do useful work in onStep. Ultimately this is
+    // where we would want to look at elapsed time since the last call
+    // to onStep completed and use a delay that gives us ~60fps.
+    while ((result = ALooper_pollAll(enabled_ ? (1000/60) : -1,
                                      NULL,
                                      &events,
                                      reinterpret_cast<void**>(&source))) >= 0) {
diff --git a/runtime/embedders/openglui/build_skia.sh b/runtime/embedders/openglui/build_skia.sh
new file mode 100755
index 0000000..34b0bb9
--- /dev/null
+++ b/runtime/embedders/openglui/build_skia.sh
@@ -0,0 +1,105 @@
+#!/bin/sh
+
+function usage {
+  echo "usage: $0 [ --help ] [ --android ] [ --arm | --x86] [--clean] [<Dart directory>]"
+  echo
+  echo "Sync up Skia and build"
+  echo
+  echo " --android: Build for Android"
+  echo " --x86 : Build for Intel"
+  echo " --arm : Cross-compile for ARM (implies --android)"
+  echo
+}
+
+DO_ANDROID=0
+TARGET_ARCH=x86
+CLEAN=0
+DART_DIR=../../..
+
+while [ ! -z "$1" ] ; do
+  case $1 in
+    "-h"|"-?"|"-help"|"--help")
+      usage
+      exit 1
+    ;;
+    "--android")
+      DO_ANDROID=1
+    ;;
+    "--arm")
+      TARGET_ARCH=arm
+      DO_ANDROID=1
+    ;;
+    "--x86")
+      TARGET_ARCH=x86
+    ;;
+    "--clean")
+      CLEAN=1
+    ;;
+    *)
+      if [ ! -d "$1" ]
+      then
+        echo "Unrecognized argument: $1"
+        usage
+        exit 1
+      fi
+      DART_DIR="$1"
+    ;;
+  esac
+  shift
+done
+
+mkdir -p "${DART_DIR}/third_party/skia"
+pushd "${DART_DIR}/third_party/skia"
+
+if [ ${DO_ANDROID} != 0 ] ; then
+  echo "Building for Android ${TARGET_ARCH}"
+  curl http://skia.googlecode.com/svn/android/gclient.config -o .gclient
+  gclient sync
+
+  export ANDROID_SDK_ROOT=`readlink -f ../android_tools/sdk`
+
+  cd trunk
+
+  echo "Using SDK ${ANDROID_SDK_ROOT}"
+  if [ ${CLEAN} != 0 ] ; then
+    ../android/bin/android_make -d $TARGET_ARCH -j clean
+  else
+    env -i BUILDTYPE=Debug ANDROID_SDK_ROOT="${ANDROID_SDK_ROOT}" ../android/bin/android_make BUILDTYPE=Debug -d $TARGET_ARCH -j --debug=j
+    #../android/bin/android_make ANDROID_NDK= BUILDTYPE=Debug ANDROID_SDK_ROOT= -d $TARGET_ARCH -j
+    #../android/bin/android_make ANDROID_NDK= BUILDTYPE=Debug ANDROID_SDK_ROOT="${ANDROID_SDK_ROOT}" -d $TARGET_ARCH -j
+    #../android/bin/android_make BUILDTYPE=Debug ANDROID_SDK_ROOT="${ANDROID_SDK_ROOT}" -d $TARGET_ARCH -j png
+  fi
+
+else
+
+  echo "Building for desktop in `pwd`"
+  # Desktop build. Requires svn client and Python.
+
+  # Note that on Linux these packages should be installed first:
+  #
+  # libfreetype6
+  # libfreetype6-dev
+  # libpng12-0, libpng12-dev
+  # libglu1-mesa-dev
+  # mesa-common-dev
+  # freeglut3-dev
+
+  SKIA_INSTALLDIR=`pwd`
+  svn checkout http://skia.googlecode.com/svn/trunk
+  cd trunk
+  if [ ${CLEAN} != 0 ] ; then
+    echo 'Cleaning'
+    make clean
+  else
+    # Dart sets BUILDTYPE to DebugX64 which breaks Skia build.
+    make BUILDTYPE=Debug
+  fi
+  cd ..
+
+fi
+
+popd
+# TODO(gram) We should really propogate the make exit code here.
+exit 0
+
+
diff --git a/runtime/embedders/openglui/common/canvas_context.cc b/runtime/embedders/openglui/common/canvas_context.cc
new file mode 100644
index 0000000..ab6420e
--- /dev/null
+++ b/runtime/embedders/openglui/common/canvas_context.cc
@@ -0,0 +1,66 @@
+// 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.
+
+#include "embedders/openglui/common/canvas_context.h"
+
+#include <ctype.h>
+#include <string.h>
+
+#include "embedders/openglui/common/support.h"
+
+CanvasContext::CanvasContext(int16_t widthp, int16_t heightp)
+  : canvas_(NULL),
+    width_(widthp),
+    height_(heightp),
+    imageSmoothingEnabled_(true),
+    state_(NULL) {
+}
+
+CanvasContext::~CanvasContext() {
+  delete state_;
+  delete canvas_;
+}
+
+void CanvasContext::Create() {
+  canvas_ = graphics->CreateCanvas();
+  state_ = new CanvasState(canvas_);
+}
+
+void CanvasContext::DrawImage(const char* src_url,
+                              int sx, int sy,
+                              bool has_src_dimensions, int sw, int sh,
+                              int dx, int dy,
+                              bool has_dst_dimensions, int dw, int dh) {
+  SkBitmap bm;
+  // TODO(gram): We need a way to remap URLs to local file names.
+  // For now I am just using the characters after the last '/'.
+  // Note also that if we want to support URLs and network fetches,
+  // then we introduce more complexity; this can't just be an URL.
+  int pos = strlen(src_url);
+  while (--pos >= 0 && src_url[pos] != '/');
+  const char *path = src_url + pos + 1;
+  if (!SkImageDecoder::DecodeFile(path, &bm)) {
+    LOGI("Image decode of %s failed", path);
+  } else {
+    LOGI("Decode image: width=%d,height=%d", bm.width(), bm.height());
+    if (!has_src_dimensions) {
+      sw = bm.width();
+      sh = bm.height();
+    }
+    if (!has_dst_dimensions) {
+      dw = bm.width();
+      dh = bm.height();
+    }
+    state_->DrawImage(bm, sx, sy, sw, sh, dx, dy, dw, dh);
+  }
+}
+
+void CanvasContext::ClearRect(float left, float top,
+                              float width, float height) {
+  SkPaint paint;
+  paint.setStyle(SkPaint::kFill_Style);
+  paint.setColor(0xFFFFFFFF);
+  canvas_->drawRectCoords(left, top, left + width, top + height, paint);
+}
+
diff --git a/runtime/embedders/openglui/common/canvas_context.h b/runtime/embedders/openglui/common/canvas_context.h
new file mode 100644
index 0000000..665542f
--- /dev/null
+++ b/runtime/embedders/openglui/common/canvas_context.h
@@ -0,0 +1,302 @@
+// 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.
+
+#ifndef EMBEDDERS_OPENGLUI_COMMON_CANVAS_CONTEXT_H_
+#define EMBEDDERS_OPENGLUI_COMMON_CANVAS_CONTEXT_H_
+
+#include "embedders/openglui/common/canvas_state.h"
+#include "embedders/openglui/common/graphics_handler.h"
+#include "embedders/openglui/common/log.h"
+#include "embedders/openglui/common/opengl.h"
+#include "embedders/openglui/common/support.h"
+
+typedef struct ImageData {
+  int width;
+  int height;
+  GLubyte* pixels;
+
+  ImageData(int wp, int hp, GLubyte* pp)
+    : width(wp), height(hp), pixels(pp) {
+  }
+  ImageData()
+    : width(0), height(0), pixels(NULL) {
+  }
+} ImageData;
+
+class CanvasContext {
+ protected:
+  SkCanvas* canvas_;
+
+  int16_t width_, height_;
+
+  bool imageSmoothingEnabled_;
+
+  CanvasState* state_;
+
+  static inline float Radians2Degrees(float angle) {
+    return 180.0 * angle / M_PI;
+  }
+
+  inline void NotImplemented(const char* method) {
+    LOGE("Method CanvasContext::%s is not yet implemented", method);
+  }
+
+ public:
+  CanvasContext(int16_t width, int16_t height);
+  virtual ~CanvasContext();
+
+  inline void setGlobalAlpha(float alpha) {
+    state_->setGlobalAlpha(alpha);
+  }
+
+  inline void setFillColor(const char* color) {
+    state_->setFillColor(color);
+  }
+
+  inline void setStrokeColor(const char* color) {
+    state_->setStrokeColor(color);
+  }
+
+  inline void setShadowBlur(float blur) {
+    state_->setShadowBlur(blur);
+  }
+
+  inline void setShadowColor(const char* color) {
+    state_->setShadowColor(color);
+  }
+
+  inline void setShadowOffsetX(float offset) {
+    state_->setShadowOffsetX(offset);
+  }
+
+  inline void setShadowOffsetY(float offset) {
+    state_->setShadowOffsetY(offset);
+  }
+
+  // For now, we don't allow resizing.
+  // TODO(gram): fix this or remove these.
+  inline int setWidth(int widthp) {
+    return width_;
+  }
+
+  inline int setHeight(int heightp) {
+    return height_;
+  }
+
+  inline bool imageSmoothingEnabled() {
+    return imageSmoothingEnabled_;
+  }
+
+  inline void setImageSmoothingEnabled(bool enabled) {
+    // TODO(gram): We're not actually doing anything with this yet.
+    imageSmoothingEnabled_ = enabled;
+  }
+
+  inline void setGlobalCompositeOperation(const char* op) {
+    state_->setGlobalCompositeOperation(op);
+  }
+
+  inline void Save() {
+    state_ = state_->Save();
+  }
+
+  inline void Restore() {
+    CanvasState* popped_state = state_;
+    state_ = state_->Restore();
+    if (state_ != popped_state) {
+      // Only delete if the pop was successful.
+      delete popped_state;
+    }
+  }
+
+  inline void Rotate(float angle) {
+    canvas_->rotate(Radians2Degrees(angle));
+  }
+
+  inline void Translate(float x, float y) {
+    canvas_->translate(x, y);
+  }
+
+  inline void Scale(float x, float y) {
+    canvas_->scale(x, y);
+  }
+
+  inline void Transform(float a, float b,
+                        float c, float d,
+                        float e, float f) {
+    SkMatrix t;
+    // Our params are for a 3 x 2 matrix in column order:
+    //
+    // a c e
+    // b d f
+    //
+    // We need to turn this into a 3x3 matrix:
+    //
+    // a c e
+    // b d f
+    // 0 0 1
+    //
+    // and pass the params in row order:
+    t.setAll(a, c, e, b, d, f, 0, 0, 1);
+    canvas_->concat(t);
+  }
+
+  inline void setTransform(float a, float b,
+                           float c, float d,
+                           float e, float f) {
+    SkMatrix t;
+    t.setAll(a, c, e, b, d, f, 0, 0, 1);
+    canvas_->setMatrix(t);
+  }
+
+  ImageData* GetImageData(float sx, float sy, float sw, float sh) {
+    NotImplemented("GetImageData");
+    return NULL;
+  }
+
+  void PutImageData(ImageData* imageData, float  dx, float dy) {
+    NotImplemented("PutImageData");
+  }
+
+  void DrawImage(const char* src_url,
+                 int sx, int sy, bool has_src_dimensions, int sw, int sh,
+                 int dx, int dy, bool has_dst_dimensions, int dw, int dh);
+
+  inline void Clear() {
+    canvas_->drawColor(0xFFFFFFFF);
+  }
+
+  void ClearRect(float left, float top, float width, float height);
+
+  inline void FillRect(float left, float top, float width, float height) {
+    // Does not affect the path.
+    state_->FillRect(left, top, width, height);
+  }
+
+  inline void StrokeRect(float left, float top, float width, float height) {
+    // Does not affect the path.
+    state_->StrokeRect(left, top, width, height);
+  }
+
+  inline void BeginPath() {
+    state_->BeginPath();
+  }
+
+  inline void Fill() {
+    state_->Fill();
+  }
+
+  inline void Stroke() {
+    state_->Stroke();
+  }
+
+  inline void ClosePath() {
+    state_->ClosePath();
+  }
+
+  inline void MoveTo(float x, float y) {
+    state_->MoveTo(x, y);
+  }
+
+  inline void LineTo(float x, float y) {
+    state_->LineTo(x, y);
+  }
+
+  inline void QuadraticCurveTo(float cpx, float cpy, float x, float y) {
+    state_->QuadraticCurveTo(cpx, cpy, x, y);
+  }
+
+  inline void BezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y,
+                     float x, float y) {
+    state_->BezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
+  }
+
+  inline void ArcTo(float x1, float y1, float x2, float y2, float radius) {
+    state_->ArcTo(x1, y1, x2, y2, radius);
+  }
+
+  inline void Rect(float x, float y, float w, float h) {
+    state_->Rect(x, y, w, h);
+  }
+
+  inline void Arc(float x, float y, float radius,
+                  float startAngle, float endAngle,
+                  bool antiClockwise) {
+    state_->Arc(x, y, radius, startAngle, endAngle, antiClockwise);
+  }
+
+  inline void setLineWidth(double w) {
+    state_->setLineWidth(w);
+  }
+
+  inline void setLineCap(const char* lc) {
+    state_->setLineCap(lc);
+  }
+
+  inline void setLineDash(float* dashes, int len) {
+    state_->setLineDash(dashes, len);
+  }
+
+  inline void setLineDashOffset(float offset) {
+    state_->setLineDashOffset(offset);
+  }
+
+  inline void setLineJoin(const char* lj) {
+    state_->setLineJoin(lj);
+  }
+
+  inline void setMiterLimit(float limit) {
+    state_->setMiterLimit(limit);
+  }
+
+  inline const char* setFont(const char* font) {
+    return state_->setFont(font);
+  }
+
+  inline const char* setTextAlign(const char* align) {
+    return state_->setTextAlign(align);
+  }
+
+  const char* setTextBaseline(const char* baseline) {
+    return state_->setTextBaseline(baseline);
+  }
+
+  inline const char* setDirection(const char* direction) {
+    return state_->setTextDirection(direction);
+  }
+
+  inline void FillText(const char* text, float x, float y,
+                       float maxWidth = -1) {
+    state_->FillText(text, x, y, maxWidth);
+  }
+
+  inline void StrokeText(const char* text, float x, float y,
+                         float maxWidth = -1) {
+    state_->StrokeText(text, x, y, maxWidth);
+  }
+
+  inline float MeasureText(const char *text) {
+    return state_->MeasureText(text);
+  }
+
+  inline void Clip() {
+    state_->Clip();
+  }
+
+  inline void ResetClip() {
+    // TODO(gram): Check this. Is it affected by the transform?
+    canvas_->clipRect(SkRect::MakeLTRB(0, 0, width_, height_),
+                      SkRegion::kReplace_Op);
+  }
+
+  virtual void Flush() {
+    canvas_->flush();
+    graphics->Flush();
+  }
+
+  void Create();
+};
+
+#endif  // EMBEDDERS_OPENGLUI_COMMON_CANVAS_CONTEXT_H_
+
diff --git a/runtime/embedders/openglui/common/canvas_state.cc b/runtime/embedders/openglui/common/canvas_state.cc
new file mode 100644
index 0000000..696e5d3
--- /dev/null
+++ b/runtime/embedders/openglui/common/canvas_state.cc
@@ -0,0 +1,299 @@
+// 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.
+
+#include "embedders/openglui/common/canvas_state.h"
+
+#include <ctype.h>
+#include <string.h>
+
+#include "embedders/openglui/common/support.h"
+
+// Float parser. Does not handle exponents. This is
+// used to parse font sizes so it doesn't need to be full-blown.
+float ParseFloat(const char* s, int& pos) {
+  int len = strlen(s);
+  float rtn = 0.0;
+  while (pos < len && s[pos] != '.' && !isdigit(s[pos])) {
+    ++pos;
+  }
+  while (pos < len && isdigit(s[pos])) {
+    rtn = rtn * 10.0 + s[pos] - '0';
+    ++pos;
+  }
+  if (pos < len && s[pos] == '.') {
+    pos++;
+    float div = 1.0;
+    while (pos < len && isdigit(s[pos])) {
+      rtn = rtn * 10.0 + s[pos] - '0';
+      ++pos;
+      div *= 10.0;
+    }
+    rtn /= div;
+  }
+  return rtn;
+}
+
+int ParseInt(const char* s, int& pos) {
+  int len = strlen(s);
+  int rtn = 0;
+  while (pos < len && !isdigit(s[pos])) {
+    ++pos;
+  }
+  while (pos < len && isdigit(s[pos])) {
+    rtn = rtn * 10 + s[pos] - '0';
+    ++pos;
+  }
+  return rtn;
+}
+
+void CanvasState::setLineCap(const char* lc) {
+  if (strcmp(lc, "round") == 0) {
+    paint_.setStrokeCap(SkPaint::kRound_Cap);
+  } else if (strcmp(lc, "square") == 0) {
+    paint_.setStrokeCap(SkPaint::kSquare_Cap);
+  } else {
+    paint_.setStrokeCap(SkPaint::kButt_Cap);
+  }
+}
+
+void CanvasState::setLineJoin(const char* lj) {
+  if (strcmp(lj, "round") == 0) {
+    paint_.setStrokeJoin(SkPaint::kRound_Join);
+  } else if (strcmp(lj, "bevel") == 0) {
+    paint_.setStrokeJoin(SkPaint::kBevel_Join);
+  } else {
+    paint_.setStrokeJoin(SkPaint::kMiter_Join);
+  }
+}
+
+const char* CanvasState::setFont(const char*name, float size) {
+  // Font names have the form "<modifier> <size> <family>".
+  // Modifiers are "normal", "italic", "bold".
+  // Sizes have magnitude and units; e.g. "10pt", "20px".
+  const char* rtn = name;
+  if (size < 0) {
+    int pos = 0;
+    // TODO(gram): need to handle these modifiers.
+    if (strncmp(name, "normal", 6) == 0) {
+      pos = 6;
+    } else if (strncmp(name, "italic", 6) == 0) {
+      pos = 6;
+    } else if (strncmp(name, "bold", 4) == 0) {
+      pos = 4;
+    }
+    size = ParseFloat(name, pos);
+    // Font size units: px, etc. For now just px.
+    // TODO(gram): Handle other units.
+    if (strncmp(name + pos, "px", 2) == 0) {
+      pos += 2;
+    }
+    int len = strlen(name);
+    while (pos < len && isspace(name[pos])) {
+      ++pos;
+    }
+    name = name + pos;
+  }
+  SkTypeface *pTypeface = SkTypeface::CreateFromName(name, SkTypeface::kNormal);
+  paint_.setTypeface(pTypeface);
+  paint_.setTextSize(size);
+  pTypeface->unref();
+  // TODO(gram): Must return a normalized font name incorporating size, so
+  // callers can set the Dart canvas font name to an appropriate value.
+  // Actually this may not be necessary in which case we can change this
+  // method to return void.
+  return rtn;
+}
+
+const char* CanvasState::setTextAlign(const char* align) {
+  // TODO(gram): What about "start" and "end"?
+  // I don't see any an analogs in Skia.
+  if (strcmp(align, "left") == 0) {
+    paint_.setTextAlign(SkPaint::kLeft_Align);
+  } else if (strcmp(align, "right") == 0) {
+    paint_.setTextAlign(SkPaint::kRight_Align);
+  } else {
+    paint_.setTextAlign(SkPaint::kCenter_Align);
+  }
+  return align;
+}
+
+const char* CanvasState::setTextBaseline(const char* baseline) {
+  // TODO(gram): Does skia support this? It doesn't seem like
+  // it. Right now we don't use the textBaseline value, but we
+  // may have to implement this ourselves, by adjusting the y
+  // values passed to StrokeText/FillText using the font metrics.
+  if (strcmp(baseline, "top") == 0) {
+  } else if (strcmp(baseline, "middle") == 0) {
+  } else if (strcmp(baseline, "bottom") == 0) {
+  } else if (strcmp(baseline, "hanging") == 0) {
+  } else if (strcmp(baseline, "alphabetic") == 0) {
+  } else if (strcmp(baseline, "ideographic") == 0) {
+  }
+  return baseline;
+}
+
+const char* CanvasState::setTextDirection(const char* direction) {
+    // TODO(gram): Add support for this if Skia does.
+  return direction;
+}
+
+void CanvasState::setGlobalCompositeOperation(const char* op) {
+  SkXfermode::Mode mode;
+  if (strcmp(op, "source-atop") == 0) {
+    mode = SkXfermode::kSrcATop_Mode;
+  } else if (strcmp(op, "source-in") == 0) {
+    mode = SkXfermode::kSrcIn_Mode;
+  } else if (strcmp(op, "source-out") == 0) {
+    mode = SkXfermode::kSrcOut_Mode;
+  } else if (strcmp(op, "source-over") == 0) {
+    mode = SkXfermode::kSrcOver_Mode;  // Default.
+  } else if (strcmp(op, "destination-atop") == 0) {
+    mode = SkXfermode::kDstATop_Mode;
+  } else if (strcmp(op, "destination-in") == 0) {
+    mode = SkXfermode::kDstIn_Mode;
+  } else if (strcmp(op, "destination-out") == 0) {
+    mode = SkXfermode::kDstOut_Mode;
+  } else if (strcmp(op, "destination-over") == 0) {
+    mode = SkXfermode::kDstOver_Mode;
+  } else if (strcmp(op, "lighter") == 0) {
+    mode = SkXfermode::kLighten_Mode;
+  } else if (strcmp(op, "darker") == 0) {
+    mode = SkXfermode::kDarken_Mode;
+  } else if (strcmp(op, "xor") == 0) {
+    mode = SkXfermode::kXor_Mode;
+  } else if (strcmp(op, "copy") == 0) {
+    mode = SkXfermode::kSrc_Mode;
+  }
+  SkXfermode* m = SkXfermode::Create(mode);
+  // It seems we don't need unref() here. Including it causes
+  // a crash. Maybe Skia has a preallocated long-lived set of
+  // instances.
+  paint_.setXfermode(m);
+}
+
+void CanvasState::Arc(float x, float y, float radius,
+                      float startAngle, float endAngle,
+                      bool antiClockwise) {
+  SkRect rect;
+  rect.set(x - radius, y - radius, x + radius, y + radius);
+  bool doCircle = false;
+
+  static float twoPi = 2 * M_PI;
+
+  float sweep = endAngle - startAngle;
+  if (sweep >= twoPi || sweep <= -twoPi) {
+    doCircle = true;
+  }
+
+  if (!antiClockwise && endAngle <= startAngle) {
+    endAngle += 2 * M_PI;
+  } else if (antiClockwise && startAngle <= endAngle) {
+    startAngle += 2 * M_PI;
+  }
+  sweep = endAngle - startAngle;
+
+  startAngle = fmodf(startAngle, twoPi);
+  float sa = Radians2Degrees(startAngle);
+  float ea = Radians2Degrees(sweep);
+  path_->arcTo(rect, sa, ea, false);
+  if (doCircle) {
+    SkPath tmp;
+    tmp.addOval(rect);
+    tmp.addPath(*path_);
+    path_->swap(tmp);
+  }
+}
+
+int hexDigit(char c) {
+  if (c >= '0' && c <= '9') return c - '0';
+  if (c <= 'Z') return c - 'A' + 10;
+  return c - 'a' + 10;
+}
+
+// Color parser.
+// See http://www.w3.org/TR/CSS21/syndata.html#color-units.
+// There is also another format: hsl(240,100%,100%) (and hsla)
+// TODO(gram): We probably eventually want to use a table rather
+// than a big if statement.
+ColorRGBA CanvasState::GetColor(const char* color) {
+  if (color[0] == '#') {
+    int r, g, b;
+    if (strlen(color) == 7) {
+      r = hexDigit(color[1]) * 16 + hexDigit(color[2]);
+      g = hexDigit(color[3]) * 16 + hexDigit(color[4]);
+      b = hexDigit(color[5]) * 16 + hexDigit(color[6]);
+    } else if (strlen(color) == 4) {
+      r = hexDigit(color[1]) * 16 + hexDigit(color[1]);
+      g = hexDigit(color[2]) * 16 + hexDigit(color[2]);
+      b = hexDigit(color[3]) * 16 + hexDigit(color[3]);
+    }
+    return ColorRGBA(r, g, b);
+  } else if (strcmp(color, "maroon") == 0) {
+    return ColorRGBA(0x80, 0x00, 0x00);
+  } else if (strcmp(color, "red") == 0) {
+    return ColorRGBA(0xFF, 0x00, 0x00);
+  } else if (strcmp(color, "orange") == 0) {
+    return ColorRGBA(0xFF, 0xA5, 0x00);
+  } else if (strcmp(color, "yellow") == 0) {
+    return ColorRGBA(0xFF, 0xFF, 0x00);
+  } else if (strcmp(color, "olive") == 0) {
+    return ColorRGBA(0x80, 0x80, 0x00);
+  } else if (strcmp(color, "purple") == 0) {
+    return ColorRGBA(0x80, 0x00, 0x80);
+  } else if (strcmp(color, "fuschia") == 0) {
+    return ColorRGBA(0xFF, 0x00, 0xFF);
+  } else if (strcmp(color, "white") == 0) {
+    return ColorRGBA(0xFF, 0xFF, 0xFF);
+  } else if (strcmp(color, "lime") == 0) {
+    return ColorRGBA(0x00, 0xFF, 0x00);
+  } else if (strcmp(color, "green") == 0) {
+    return ColorRGBA(0x00, 0x80, 0x00);
+  } else if (strcmp(color, "navy") == 0) {
+    return ColorRGBA(0x00, 0x00, 0x80);
+  } else if (strcmp(color, "blue") == 0) {
+    return ColorRGBA(0x00, 0x00, 0xFF);
+  } else if (strcmp(color, "aqua") == 0) {
+    return ColorRGBA(0x00, 0xFF, 0xFF);
+  } else if (strcmp(color, "teal") == 0) {
+    return ColorRGBA(0x00, 0x80, 0x80);
+  } else if (strcmp(color, "silver") == 0) {
+    return ColorRGBA(0xC0, 0xC0, 0xC0);
+  } else if (strcmp(color, "gray") == 0) {
+    return ColorRGBA(0x80, 0x80, 0x80);
+  } else if (strncmp(color, "rgb(", 4) == 0) {
+    int pos = 4;
+    int r = ParseInt(color, pos);
+    ++pos;
+    int g = ParseInt(color, pos);
+    ++pos;
+    int b = ParseInt(color, pos);
+    return ColorRGBA(r, g, b);
+  } else if (strncmp(color, "rgba(", 5) == 0) {
+    int pos = 5;
+    int r = ParseInt(color, pos);
+    ++pos;
+    int g = ParseInt(color, pos);
+    ++pos;
+    int b = ParseInt(color, pos);
+    ++pos;
+    float a = ParseFloat(color, pos);
+    return ColorRGBA(r, g, b, static_cast<int>(a * 255.0));
+  }
+  // Default to black.
+  return ColorRGBA(0x00, 0x00, 0x00);
+}
+
+void CanvasState::DrawImage(const SkBitmap& bm,
+                            int sx, int sy, int sw, int sh,
+                            int dx, int dy, int dw, int dh) {
+  if (sw < 0) sw = bm.width();
+  if (dw < 0) dw = bm.width();
+  if (sh < 0) sh = bm.height();
+  if (dh < 0) dh = bm.height();
+  SkIRect src = SkIRect::MakeXYWH(sx, sy, sw, sh);
+  SkRect dst = SkRect::MakeXYWH(dx, dy, dw, dh);
+  LOGI("DrawImage(_,%d,%d,%d,%d,%d,%d,%d,%d)", sx, sy, sw, sh, dx, dy, dw, dh);
+  canvas_->drawBitmapRect(bm, &src, dst);
+}
+
diff --git a/runtime/embedders/openglui/common/canvas_state.h b/runtime/embedders/openglui/common/canvas_state.h
new file mode 100644
index 0000000..45581ed
--- /dev/null
+++ b/runtime/embedders/openglui/common/canvas_state.h
@@ -0,0 +1,309 @@
+// 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.
+
+#ifndef EMBEDDERS_OPENGLUI_COMMON_CANVAS_STATE_H_
+#define EMBEDDERS_OPENGLUI_COMMON_CANVAS_STATE_H_
+
+#include "embedders/openglui/common/graphics_handler.h"
+#include "embedders/openglui/common/log.h"
+#include "embedders/openglui/common/opengl.h"
+#include "embedders/openglui/common/support.h"
+
+typedef struct CanvasState {
+  SkPaint paint_;
+  float globalAlpha_;
+  float miterLimit_;
+  ColorRGBA fillColor_;
+  ColorRGBA strokeColor_;
+  ColorRGBA shadowColor_;
+  float shadowBlur_;
+  float shadowOffsetX_;
+  float shadowOffsetY_;
+  float* lineDash_;
+  int lineDashCount_;
+  int lineDashOffset_;
+
+  SkPath* path_;
+  SkCanvas* canvas_;
+  CanvasState* next_;  // For stack.
+
+  CanvasState(SkCanvas* canvas)
+    : paint_(),
+      globalAlpha_(1.0),
+      miterLimit_(10),
+      fillColor_(ColorRGBA(255, 0, 0, 255)),
+      strokeColor_(fillColor_),
+      shadowColor_(ColorRGBA(0, 0, 0, 0)),
+      shadowBlur_(0.0),
+      shadowOffsetX_(0.0),
+      shadowOffsetY_(0.0),
+      lineDash_(NULL),
+      lineDashCount_(0),
+      lineDashOffset_(0),
+      path_(new SkPath()),
+      canvas_(canvas),
+      next_(NULL) {
+    paint_.setStrokeCap(SkPaint::kButt_Cap);
+    paint_.setStrokeJoin(SkPaint::kMiter_Join);
+    paint_.setStrokeWidth(1);
+    paint_.setTextAlign(SkPaint::kLeft_Align);
+    paint_.setAntiAlias(true);
+    paint_.setStyle(SkPaint::kStroke_Style);
+    setFont("Helvetica", 10);
+  }
+
+  CanvasState(const CanvasState& state)
+    : paint_(state.paint_),
+      globalAlpha_(state.globalAlpha_),
+      miterLimit_(state.miterLimit_),
+      fillColor_(state.fillColor_),
+      strokeColor_(state.strokeColor_),
+      shadowColor_(state.shadowColor_),
+      shadowBlur_(state.shadowBlur_),
+      shadowOffsetX_(state.shadowOffsetX_),
+      shadowOffsetY_(state.shadowOffsetY_),
+      lineDash_(NULL),
+      lineDashCount_(state.lineDashCount_),
+      lineDashOffset_(state.lineDashOffset_),
+      path_(new SkPath()),
+      canvas_(state.canvas_),
+      next_(NULL) {
+    setLineDash(state.lineDash_, lineDashCount_);
+  }
+
+  ~CanvasState() {
+    delete path_;
+    delete[] lineDash_;
+  }
+
+  static ColorRGBA GetColor(const char* color);
+
+  inline CanvasState* Save() {
+    canvas_->save();  // For clip and transform.
+    CanvasState *new_state = new CanvasState(*this);
+    new_state->next_ = this;
+    // If the old state has a non-empty path, use its
+    // last point as the new states first point.
+    int np = path_->countPoints();
+    if (np > 0) {
+      new_state->path_->moveTo(path_->getPoint(np-1));
+    }
+    return new_state;
+  }
+
+  inline CanvasState* Restore() {
+    if (next_ != NULL) {
+      // If the state we are popping has a non-empty path,
+      // apply the state's transform to the path, then
+      // add the path to the previous state's path.
+      if (path_->countPoints() > 0) {
+        path_->transform(canvas_->getTotalMatrix());
+        next_->path_->addPath(*path_);
+      }
+      canvas_->restore();
+      return next_;
+    }
+    canvas_->restore();
+    return next_;  // TODO(gram): Should we assert/throw?
+  }
+
+  inline float Radians2Degrees(float angle) {
+    return 180.0 * angle / M_PI;
+  }
+
+  inline void setGlobalAlpha(float alpha) {
+    globalAlpha_ = alpha;
+  }
+
+  inline void setFillColor(const char* color) {
+    fillColor_ = GetColor(color);
+  }
+
+  inline void setStrokeColor(const char* color) {
+    strokeColor_ = GetColor(color);
+  }
+
+  const char* setFont(const char*name, float size = -1);
+  void setLineCap(const char* lc);
+  void setLineJoin(const char* lj);
+
+  inline void setMiterLimit(float limit) {
+    miterLimit_ = limit;
+  }
+
+  const char* setTextAlign(const char* align);
+  const char* setTextBaseline(const char* baseline);
+  const char* setTextDirection(const char* direction);
+
+  inline void FillText(const char* text, float x, float y, float maxWidth) {
+    setFillMode();
+    canvas_->drawText(text, strlen(text), x, y, paint_);
+  }
+
+  inline void StrokeText(const char* text, float x, float y, float maxWidth) {
+    setStrokeMode();
+    canvas_->drawText(text, strlen(text), x, y, paint_);
+  }
+
+  inline float MeasureText(const char *text) {
+    // TODO(gram): make sure this is not supposed to be affected
+    // by the canvas transform.
+    return paint_.measureText(text, strlen(text));
+  }
+
+  inline void setLineWidth(float w) {
+    paint_.setStrokeWidth(w);
+  }
+
+  inline void setMode(SkPaint::Style style, ColorRGBA color) {
+    paint_.setStyle(style);
+    paint_.setColor(color.v);
+    uint8_t alpha = static_cast<uint8_t>(
+        globalAlpha_ * static_cast<float>(color.alpha()));
+    paint_.setAlpha(alpha);
+    bool drawShadow = (shadowOffsetX_ != 0 ||
+                       shadowOffsetY_ != 0 ||
+                       shadowBlur_ != 0) &&
+                       shadowColor_.alpha() > 0;
+    if (drawShadow) {
+      // TODO(gram): should we mult shadowColor by globalAlpha?
+      paint_.setLooper(new SkBlurDrawLooper(SkFloatToScalar(shadowBlur_),
+                                            SkFloatToScalar(shadowOffsetX_),
+                                            SkFloatToScalar(shadowOffsetY_),
+                                            shadowColor_.v))->unref();
+    } else {
+      paint_.setLooper(NULL);
+    }
+  }
+
+  inline void setLineDashEffect() {
+    if (lineDashCount_ > 0) {
+      SkDashPathEffect* dashPathEffect =
+        new SkDashPathEffect(lineDash_, lineDashCount_, lineDashOffset_);
+        paint_.setPathEffect(dashPathEffect)->unref();
+    } else {
+      paint_.setPathEffect(NULL);
+    }
+  }
+
+  inline void setLineDash(float* dashes, int len) {
+    if (len == 0) {
+      lineDashCount_ = 0;
+      delete[] lineDash_;
+      lineDash_ = NULL;
+    } else {
+      lineDash_ = new float[lineDashCount_ = len];
+      for (int i = 0; i < len; i++) {
+        lineDash_[i] = dashes[i];
+      }
+    }
+    setLineDashEffect();
+  }
+
+  inline void setLineDashOffset(int offset) {
+    if (offset != lineDashOffset_) {
+      lineDashOffset_ = offset;
+      setLineDashEffect();
+    }
+  }
+
+  inline void setShadowColor(const char* color) {
+    shadowColor_ = GetColor(color);
+  }
+
+  inline void setShadowBlur(float blur) {
+    shadowBlur_ = blur;
+  }
+
+  inline void setShadowOffsetX(float ox) {
+    shadowOffsetX_ = ox;
+  }
+
+  inline void setShadowOffsetY(float oy) {
+    shadowOffsetY_ = oy;
+  }
+
+  inline void setFillMode() {
+    setMode(SkPaint::kFill_Style, fillColor_);
+  }
+
+  inline void setStrokeMode() {
+    setMode(SkPaint::kStroke_Style, strokeColor_);
+  }
+
+  inline void FillRect(float left, float top,
+                       float width, float height) {
+    // Does not affect the path.
+    setFillMode();
+    canvas_->drawRectCoords(left, top, left + width, top + height, paint_);
+  }
+
+  inline void StrokeRect(float left, float top,
+                         float width, float height) {
+    // Does not affect the path.
+    setStrokeMode();
+    canvas_->drawRectCoords(left, top, left + width, top + height, paint_);
+  }
+
+  inline void BeginPath() {
+    path_->rewind();
+  }
+
+  inline void Fill() {
+    setFillMode();
+    canvas_->drawPath(*path_, paint_);
+  }
+
+  inline void Stroke() {
+    setStrokeMode();
+    canvas_->drawPath(*path_, paint_);
+  }
+
+  inline void ClosePath() {
+    path_->close();
+  }
+
+  inline void MoveTo(float x, float y) {
+    path_->moveTo(x, y);
+  }
+
+  inline void LineTo(float x, float y) {
+    path_->lineTo(x, y);
+  }
+
+  void Arc(float x, float y, float radius, float startAngle, float endAngle,
+           bool antiClockwise);
+
+  inline void QuadraticCurveTo(float cpx, float cpy, float x, float y) {
+    path_->quadTo(cpx, cpy, x, y);
+  }
+
+  inline void BezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y,
+                     float x, float y) {
+    path_->cubicTo(cp1x, cp1y, cp2x, cp2y, x, y);
+  }
+
+  inline void ArcTo(float x1, float y1, float x2, float y2, float radius) {
+    path_->arcTo(x1, y1, x2, y2, radius);
+  }
+
+  inline void Rect(float x, float y, float w, float h) {
+    // TODO(gram): Should we draw this directly? If so, what happens with the
+    // path?
+    path_->addRect(x, y, x + w, y + h);
+  }
+
+  void setGlobalCompositeOperation(const char* op);
+
+  void DrawImage(const SkBitmap& bm,
+                 int sx, int sy, int sw, int sh,
+                 int dx, int dy, int dw, int dh);
+
+  inline void Clip() {
+    canvas_->clipPath(*path_);
+  }
+} CanvasState;
+
+#endif  // EMBEDDERS_OPENGLUI_COMMON_CANVAS_STATE_H_
+
diff --git a/runtime/embedders/openglui/common/dart_host.cc b/runtime/embedders/openglui/common/dart_host.cc
index fae2eb4..8e8c2a6 100644
--- a/runtime/embedders/openglui/common/dart_host.cc
+++ b/runtime/embedders/openglui/common/dart_host.cc
@@ -39,7 +39,7 @@
     if (input_handler_->Start() != 0) {
       return -1;
     }
-    timer_->reset();
+    timer_->Reset();
     LOGI("Starting main isolate");
     int result = vm_glue_->StartMainIsolate();
     if (result != 0) {
@@ -47,7 +47,7 @@
       return -1;
     }
     active_ = true;
-    vm_glue_->CallSetup();
+    return vm_glue_->CallSetup();
   }
   return 0;
 }
@@ -68,9 +68,9 @@
 }
 
 int32_t DartHost::OnStep() {
-  timer_->update();
-  vm_glue_->CallUpdate();
-  if (graphics_handler_->Update() != 0) {
+  timer_->Update();
+  if (vm_glue_->CallUpdate() != 0 ||
+      graphics_handler_->Update() != 0) {
     return -1;
   }
   return 0;
diff --git a/runtime/embedders/openglui/common/extension.cc b/runtime/embedders/openglui/common/extension.cc
index 2f3b90d..40b92f4 100644
--- a/runtime/embedders/openglui/common/extension.cc
+++ b/runtime/embedders/openglui/common/extension.cc
@@ -8,6 +8,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "embedders/openglui/common/canvas_context.h"
+#include "embedders/openglui/common/graphics_handler.h"
 #include "embedders/openglui/common/log.h"
 #include "embedders/openglui/common/opengl.h"
 #include "include/dart_api.h"
@@ -153,6 +155,11 @@
   Dart_SetReturnValue(arguments, result);
 }
 
+void SetDoubleReturnValue(Dart_NativeArguments arguments, double v) {
+  Dart_Handle result = HandleError(Dart_NewDouble(v));
+  Dart_SetReturnValue(arguments, result);
+}
+
 void SetStringReturnValue(Dart_NativeArguments arguments, const char* s) {
   Dart_Handle result = HandleError(Dart_NewStringFromCString(s));
   Dart_SetReturnValue(arguments, result);
@@ -194,6 +201,20 @@
   Dart_ExitScope();
 }
 
+void GetDeviceScreenWidth(Dart_NativeArguments arguments) {
+  LOGI("GetDeviceScreenWidth");
+  Dart_EnterScope();
+  SetIntReturnValue(arguments, graphics->width());
+  Dart_ExitScope();
+}
+
+void GetDeviceScreenHeight(Dart_NativeArguments arguments) {
+  LOGI("GetDeviceScreenHeight");
+  Dart_EnterScope();
+  SetIntReturnValue(arguments, graphics->height());
+  Dart_ExitScope();
+}
+
 void SwapBuffers(Dart_NativeArguments arguments) {
   LOGI("SwapBuffers");
   Dart_EnterScope();
@@ -900,6 +921,605 @@
   Dart_ExitScope();
 }
 
+// 2D Canvas.
+
+// TODO(gram): this should be dynamic.
+#define MAX_CONTEXTS 16
+CanvasContext* contexts[MAX_CONTEXTS] = { 0 };
+
+CanvasContext* display_context;
+
+CanvasContext* Context2D(int handle) {
+  if (handle < 0 || handle >= MAX_CONTEXTS) {
+    return NULL;
+  }
+  return contexts[handle];
+}
+
+void C2DCreateNativeContext(Dart_NativeArguments arguments) {
+  LOGI("In C2DCreateNativeContext");
+  Dart_EnterScope();
+
+  int handle = GetArgAsInt(arguments, 0);
+  int width = GetArgAsInt(arguments, 1);
+  int height = GetArgAsInt(arguments, 2);
+
+  // ASSERT(handle >= 0 && handle < MAX_CONTEXTS &&
+  //          contexts[handle] == NULL)
+  CanvasContext* rtn = new CanvasContext(width, height);
+  rtn->Create();
+  if (display_context == NULL) {
+    display_context = rtn;
+  }
+  contexts[handle] = rtn;
+  Dart_ExitScope();
+  LOGI("Out C2DCreateNativeContext");
+}
+
+void C2DSetWidth(Dart_NativeArguments arguments) {
+  LOGI("In C2DSetWidth");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  int width = GetArgAsInt(arguments, 1);
+  SetIntReturnValue(arguments, Context2D(handle)->setWidth(width));
+  Dart_ExitScope();
+  LOGI("Out C2DSetWidth");
+}
+
+void C2DSetHeight(Dart_NativeArguments arguments) {
+  LOGI("In C2DSetHeight");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  int height = GetArgAsInt(arguments, 1);
+  SetIntReturnValue(arguments, Context2D(handle)->setHeight(height));
+  Dart_ExitScope();
+  LOGI("Out C2DSetHeight");
+}
+
+void C2DSetGlobalAlpha(Dart_NativeArguments arguments) {
+  LOGI("In C2DSetGlobalAlpha");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double alpha = GetArgAsDouble(arguments, 1);
+  alpha = MIN(1.0, MAX(alpha, 0.0));
+  Context2D(handle)->setGlobalAlpha(alpha);
+  SetDoubleReturnValue(arguments, alpha);
+  Dart_ExitScope();
+  LOGI("Out C2DSetGlobalAlpha");
+}
+
+void C2DSetFillStyle(Dart_NativeArguments arguments) {
+  LOGI("In C2DSetFillStyle");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  Dart_Handle whatHandle = HandleError(Dart_GetNativeArgument(arguments, 1));
+  if (Dart_IsString(whatHandle)) {
+    const char* color = GetArgAsString(arguments, 1);
+    Context2D(handle)->setFillColor(color);
+  } else {  // Texture from gradient or image.
+  }
+  Dart_ExitScope();
+  LOGI("Out C2DSetFillStyle");
+}
+
+void C2DSetFont(Dart_NativeArguments arguments) {
+  LOGI("In C2DSetFont");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  const char* font = GetArgAsString(arguments, 1);
+  SetStringReturnValue(arguments, Context2D(handle)->setFont(font));
+  Dart_ExitScope();
+  LOGI("Out C2DSetFont");
+}
+
+void C2DSetGlobalCompositeOperation(Dart_NativeArguments arguments) {
+  LOGI("In C2DSetGlobalCompositeOperation");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  const char* op = GetArgAsString(arguments, 1);
+  Context2D(handle)->setGlobalCompositeOperation(op);
+  Dart_ExitScope();
+  LOGI("Out C2DSetGlobalCompositeOperation");
+}
+
+void C2DSetLineCap(Dart_NativeArguments arguments) {
+  LOGI("In C2DSetLineCap");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  const char* lc = GetArgAsString(arguments, 1);
+  Context2D(handle)->setLineCap(lc);
+  Dart_ExitScope();
+  LOGI("Out C2DSetLineCap");
+}
+
+void C2DSetLineJoin(Dart_NativeArguments arguments) {
+  LOGI("In C2DSetLineJoin");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  const char* lj = GetArgAsString(arguments, 1);
+  Context2D(handle)->setLineJoin(lj);
+  Dart_ExitScope();
+  LOGI("Out C2DSetLineJoin");
+}
+
+void C2DSetLineWidth(Dart_NativeArguments arguments) {
+  LOGI("In C2DSetLineWidth");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double w = GetArgAsDouble(arguments, 1);
+  Context2D(handle)->setLineWidth(w);
+  Dart_ExitScope();
+  LOGI("Out C2DSetLineWidth");
+}
+
+void C2DSetMiterLimit(Dart_NativeArguments arguments) {
+  LOGI("In C2DSetMiterLimit");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double w = GetArgAsDouble(arguments, 1);
+  Context2D(handle)->setMiterLimit(w);
+  Dart_ExitScope();
+  LOGI("Out C2DSetMiterLimit");
+}
+
+void C2DSetShadowBlur(Dart_NativeArguments arguments) {
+  LOGI("In C2DSetShadowBlur");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double blur = GetArgAsDouble(arguments, 1);
+  Context2D(handle)->setShadowBlur(blur);
+  Dart_ExitScope();
+  LOGI("Out C2DSetShadowBlur");
+}
+
+void C2DSetShadowColor(Dart_NativeArguments arguments) {
+  LOGI("In C2DSetShadowColor");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  const char* color = GetArgAsString(arguments, 1);
+  Context2D(handle)->setShadowColor(color);
+  Dart_ExitScope();
+  LOGI("Out C2DSetShadowColor");
+}
+
+void C2DSetShadowOffsetX(Dart_NativeArguments arguments) {
+  LOGI("In C2DSetShadowOffsetX");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double offset = GetArgAsDouble(arguments, 1);
+  Context2D(handle)->setShadowOffsetX(offset);
+  Dart_ExitScope();
+  LOGI("Out C2DSetShadowOffsetX");
+}
+
+void C2DSetShadowOffsetY(Dart_NativeArguments arguments) {
+  LOGI("In C2DSetShadowOffsetY");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double offset = GetArgAsDouble(arguments, 1);
+  Context2D(handle)->setShadowOffsetY(offset);
+  Dart_ExitScope();
+  LOGI("Out C2DSetShadowOffsetY");
+}
+
+void C2DSetStrokeStyle(Dart_NativeArguments arguments) {
+  LOGI("In C2DSetStrokeStyle");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  const char* color = GetArgAsString(arguments, 1);
+  Context2D(handle)->setStrokeColor(color);
+  Dart_ExitScope();
+  LOGI("Out C2DSetStrokeStyle");
+}
+
+void C2DSetTextAlign(Dart_NativeArguments arguments) {
+  LOGI("In C2DSetTextAlign");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  const char* align = GetArgAsString(arguments, 1);
+  SetStringReturnValue(arguments, Context2D(handle)->setTextAlign(align));
+  Dart_ExitScope();
+  LOGI("Out C2DSetTextAlign");
+}
+
+void C2DSetTextBaseline(Dart_NativeArguments arguments) {
+  LOGI("In C2DSetTextBaseline");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  const char* baseline = GetArgAsString(arguments, 1);
+  SetStringReturnValue(arguments, Context2D(handle)->setTextBaseline(baseline));
+  Dart_ExitScope();
+  LOGI("Out C2DSetTextBaseline");
+}
+
+void C2DGetImageSmoothingEnabled(Dart_NativeArguments arguments) {
+  LOGI("In C2DGetImageSmoothingEnabled");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  SetDoubleReturnValue(arguments, Context2D(handle)->imageSmoothingEnabled());
+  Dart_ExitScope();
+  LOGI("Out C2DGetImageSmoothingEnabled");
+}
+
+void C2DArc(Dart_NativeArguments arguments) {
+  LOGI("In C2DArc");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double x = GetArgAsDouble(arguments, 1);
+  double y = GetArgAsDouble(arguments, 2);
+  double r = GetArgAsDouble(arguments, 3);
+  double a1 = GetArgAsDouble(arguments, 4);
+  double a2 = GetArgAsDouble(arguments, 5);
+  bool anticlockwise = GetArgAsBool(arguments, 6);
+  Context2D(handle)->Arc(x, y, r, a1, a2, anticlockwise);
+  Dart_ExitScope();
+  LOGI("Out C2DArc");
+}
+
+void C2DArcTo(Dart_NativeArguments arguments) {
+  LOGI("In C2DArcTo");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double x1 = GetArgAsDouble(arguments, 1);
+  double y1 = GetArgAsDouble(arguments, 2);
+  double x2 = GetArgAsDouble(arguments, 3);
+  double y2 = GetArgAsDouble(arguments, 4);
+  double radius = GetArgAsDouble(arguments, 5);
+  Context2D(handle)->ArcTo(x1, y1, x2, y2, radius);
+  Dart_ExitScope();
+  LOGI("Out C2DArcTo");
+}
+
+void C2DBeginPath(Dart_NativeArguments arguments) {
+  LOGI("In C2DBeginPath");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  Context2D(handle)->BeginPath();
+  Dart_ExitScope();
+  LOGI("Out C2DBeginPath");
+}
+
+void C2DBezierCurveTo(Dart_NativeArguments arguments) {
+  LOGI("In C2DBezierCurveTo");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double cp1x = GetArgAsDouble(arguments, 1);
+  double cp1y = GetArgAsDouble(arguments, 2);
+  double cp2x = GetArgAsDouble(arguments, 3);
+  double cp2y = GetArgAsDouble(arguments, 4);
+  double x = GetArgAsDouble(arguments, 5);
+  double y = GetArgAsDouble(arguments, 6);
+  Context2D(handle)->BezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
+  Dart_ExitScope();
+  LOGI("Out C2DBezierCurveTo");
+}
+
+void C2DClearRect(Dart_NativeArguments arguments) {
+  LOGI("In C2DClearRect");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double left = GetArgAsDouble(arguments, 1);
+  double top = GetArgAsDouble(arguments, 2);
+  double width = GetArgAsDouble(arguments, 3);
+  double height = GetArgAsDouble(arguments, 4);
+  Context2D(handle)->ClearRect(left, top, width, height);
+  Dart_ExitScope();
+  LOGI("Out C2DClearRect");
+}
+
+void C2DClip(Dart_NativeArguments arguments) {
+  LOGI("In C2DClip");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  Context2D(handle)->Clip();
+  Dart_ExitScope();
+  LOGI("Out C2DClip");
+}
+
+void C2DClosePath(Dart_NativeArguments arguments) {
+  LOGI("In C2DClosePath");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  Context2D(handle)->ClosePath();
+  Dart_ExitScope();
+  LOGI("Out C2DClosePath");
+}
+
+void C2DCreateImageDataFromDimensions(Dart_NativeArguments arguments) {
+  LOGI("In C2DCreateImageDataFromDimensions");
+  Dart_EnterScope();
+  // int handle = GetArgAsInt(arguments, 0);
+  // double sw = GetArgAsDouble(arguments, 1);
+  // double sh = GetArgAsDouble(arguments, 2);
+  // GLubyte* pixels = (GLubyte*)calloc(sw * sh * 4, sizeof(GLubyte));
+  // ImageData* imageData = new ImageData(sw, sh, pixels);
+  // TODO(gram): How do we create a Dart ImageData object from this?
+  Dart_ExitScope();
+  LOGI("Out C2DCreateImageDataFromDimensions");
+}
+
+void C2DDrawImage(Dart_NativeArguments arguments) {
+  LOGI("In C2DDrawImage");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  const char* src_url = GetArgAsString(arguments, 1);
+  int sx = GetArgAsInt(arguments, 2);
+  int sy = GetArgAsInt(arguments, 3);
+  bool has_src_dimensions = GetArgAsBool(arguments, 4);
+  int sw = GetArgAsInt(arguments, 5);
+  int sh = GetArgAsInt(arguments, 6);
+  int dx = GetArgAsInt(arguments, 7);
+  int dy = GetArgAsInt(arguments, 8);
+  bool has_dst_dimensions = GetArgAsBool(arguments, 9);
+  int dw = GetArgAsInt(arguments, 10);
+  int dh = GetArgAsInt(arguments, 11);
+  Context2D(handle)->DrawImage(src_url,
+                               sx, sy, has_src_dimensions, sw, sh,
+                               dx, dy, has_dst_dimensions, dw, dh);
+  Dart_ExitScope();
+  LOGI("Out C2DDrawImage");
+}
+
+void C2DFill(Dart_NativeArguments arguments) {
+  LOGI("In C2DFill");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  Context2D(handle)->Fill();
+  Dart_ExitScope();
+  LOGI("Out C2DFill");
+}
+
+void C2DFillRect(Dart_NativeArguments arguments) {
+  LOGI("In C2DFillRect");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double left = GetArgAsDouble(arguments, 1);
+  double top = GetArgAsDouble(arguments, 2);
+  double width = GetArgAsDouble(arguments, 3);
+  double height = GetArgAsDouble(arguments, 4);
+  Context2D(handle)->FillRect(left, top, width, height);
+  Dart_ExitScope();
+  LOGI("Out C2DFillRect");
+}
+
+void C2DFillText(Dart_NativeArguments arguments) {
+  LOGI("In C2DFillText");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  const char* text = GetArgAsString(arguments, 1);
+  double x = GetArgAsDouble(arguments, 2);
+  double y = GetArgAsDouble(arguments, 3);
+  double maxWidth = GetArgAsDouble(arguments, 4);
+  Context2D(handle)->FillText(text, x, y, maxWidth);
+  Dart_ExitScope();
+  LOGI("Out C2DFillText");
+}
+
+void C2DGetImageData(Dart_NativeArguments arguments) {
+  LOGI("In C2DGetImageData");
+  Dart_EnterScope();
+  // TODO(gram): Complete this.
+  // int handle = GetArgAsInt(arguments, 0);
+  // double sx = GetArgAsDouble(arguments, 1);
+  // double sy = GetArgAsDouble(arguments, 2);
+  // double sw = GetArgAsDouble(arguments, 3);
+  // double sh = GetArgAsDouble(arguments, 4);
+  // ... = Context2D(handle)->GetImageData(text, x, y, maxWidth);
+  Dart_ExitScope();
+  LOGI("Out C2DGetImageData");
+}
+
+void C2DLineTo(Dart_NativeArguments arguments) {
+  LOGI("In C2DLineTo");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double x = GetArgAsDouble(arguments, 1);
+  double y = GetArgAsDouble(arguments, 2);
+  Context2D(handle)->LineTo(x, y);
+  Dart_ExitScope();
+  LOGI("Out C2DLineTo");
+}
+
+void C2DMeasureText(Dart_NativeArguments arguments) {
+  LOGI("In C2DMeasureText");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  const char* text = GetArgAsString(arguments, 1);
+  float width = Context2D(handle)->MeasureText(text);
+  SetDoubleReturnValue(arguments, width);
+  Dart_ExitScope();
+  LOGI("Out C2DMeasureText");
+}
+
+void C2DMoveTo(Dart_NativeArguments arguments) {
+  LOGI("IN C2DMoveTo");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double x = GetArgAsDouble(arguments, 1);
+  double y = GetArgAsDouble(arguments, 2);
+  Context2D(handle)->MoveTo(x, y);
+  Dart_ExitScope();
+  LOGI("Out C2DMoveTo");
+}
+
+void C2DPutImageData(Dart_NativeArguments arguments) {
+  LOGI("IN C2DPutImageData");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  // Get object arguments 2
+  // BindingImageData* imageData = GetArgAsObject(arguments, 1);
+  double dx = GetArgAsDouble(arguments, 2);
+  double dy = GetArgAsDouble(arguments, 3);
+  Context2D(handle)->PutImageData(NULL, dx, dy);
+  Dart_ExitScope();
+  LOGI("Out C2DPutImageData");
+}
+
+void C2DQuadraticCurveTo(Dart_NativeArguments arguments) {
+  LOGI("In C2DQuadraticCurveTo");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double cpx = GetArgAsDouble(arguments, 1);
+  double cpy = GetArgAsDouble(arguments, 2);
+  double x = GetArgAsDouble(arguments, 3);
+  double y = GetArgAsDouble(arguments, 4);
+  Context2D(handle)->QuadraticCurveTo(cpx, cpy, x, y);
+  Dart_ExitScope();
+  LOGI("Out C2DQuadraticCurveTo");
+}
+
+void C2DRect(Dart_NativeArguments arguments) {
+  LOGI("In C2DRect");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double x = GetArgAsDouble(arguments, 1);
+  double y = GetArgAsDouble(arguments, 2);
+  double w = GetArgAsDouble(arguments, 3);
+  double h = GetArgAsDouble(arguments, 4);
+  Context2D(handle)->Rect(x, y, w, h);
+  Dart_ExitScope();
+  LOGI("Out C2DRect");
+}
+
+void C2DRestore(Dart_NativeArguments arguments) {
+  LOGI("In C2DRestore");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  Context2D(handle)->Restore();
+  Dart_ExitScope();
+  LOGI("Out C2DRestore");
+}
+
+void C2DRotate(Dart_NativeArguments arguments) {
+  LOGI("In C2DRotate");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double a = GetArgAsDouble(arguments, 1);
+  Context2D(handle)->Rotate(a);
+  Dart_ExitScope();
+  LOGI("Out C2DRotate");
+}
+
+void C2DSave(Dart_NativeArguments arguments) {
+  LOGI("In C2DSave");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  Context2D(handle)->Save();
+  Dart_ExitScope();
+  LOGI("Out C2DSave");
+}
+
+void C2DScale(Dart_NativeArguments arguments) {
+  LOGI("In C2DScale");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double sx = GetArgAsDouble(arguments, 1);
+  double sy = GetArgAsDouble(arguments, 2);
+  Context2D(handle)->Scale(sx, sy);
+  Dart_ExitScope();
+  LOGI("Out C2DScale");
+}
+
+void C2DSetLineDash(Dart_NativeArguments arguments) {
+  LOGI("In C2DSetLineDash");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  int len;
+  float* dash = static_cast<float*>(GetArgsAsFloatList(arguments, 1, &len));
+  if (dash != NULL) {
+    Context2D(handle)->setLineDash(dash, len);
+    delete[] dash;
+  }
+  Dart_ExitScope();
+  LOGI("Out C2DSetLineDash");
+}
+
+void C2DSetLineDashOffset(Dart_NativeArguments arguments) {
+  LOGI("In C2DSetLineDashOffset");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double offset = GetArgAsDouble(arguments, 1);
+  Context2D(handle)->setLineDashOffset(offset);
+  Dart_ExitScope();
+  LOGI("Out C2DSetLineDashOffset");
+}
+
+void C2DSetTransform(Dart_NativeArguments arguments) {
+  LOGI("In C2DSetTransform");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double m11 = GetArgAsDouble(arguments, 1);
+  double m12 = GetArgAsDouble(arguments, 2);
+  double m21 = GetArgAsDouble(arguments, 3);
+  double m22 = GetArgAsDouble(arguments, 4);
+  double dx = GetArgAsDouble(arguments, 5);
+  double dy = GetArgAsDouble(arguments, 6);
+  Context2D(handle)->setTransform(m11, m12, m21, m22, dx, dy);
+  Dart_ExitScope();
+  LOGI("Out C2DSetTransform");
+}
+
+void C2DStroke(Dart_NativeArguments arguments) {
+  LOGI("In C2DStroke");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  Context2D(handle)->Stroke();
+  Dart_ExitScope();
+  LOGI("Out C2DStroke");
+}
+
+void C2DStrokeRect(Dart_NativeArguments arguments) {
+  LOGI("In C2DStrokeRect");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double left = GetArgAsDouble(arguments, 1);
+  double top = GetArgAsDouble(arguments, 2);
+  double width = GetArgAsDouble(arguments, 3);
+  double height = GetArgAsDouble(arguments, 4);
+  Context2D(handle)->StrokeRect(left, top, width, height);
+  Dart_ExitScope();
+  LOGI("Out C2DStrokeRect");
+}
+
+void C2DStrokeText(Dart_NativeArguments arguments) {
+  LOGI("In C2DStrokeText");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  const char* text = GetArgAsString(arguments, 1);
+  double x = GetArgAsDouble(arguments, 2);
+  double y = GetArgAsDouble(arguments, 3);
+  double maxWidth = GetArgAsDouble(arguments, 4);
+  Context2D(handle)->StrokeText(text, x, y, maxWidth);
+  Dart_ExitScope();
+  LOGI("Out C2DStrokeText");
+}
+
+void C2DTransform(Dart_NativeArguments arguments) {
+  LOGI("In C2DTransform");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double m11 = GetArgAsDouble(arguments, 1);
+  double m12 = GetArgAsDouble(arguments, 2);
+  double m21 = GetArgAsDouble(arguments, 3);
+  double m22 = GetArgAsDouble(arguments, 4);
+  double dx = GetArgAsDouble(arguments, 5);
+  double dy = GetArgAsDouble(arguments, 6);
+  Context2D(handle)->Transform(m11, m12, m21, m22, dx, dy);
+  Dart_ExitScope();
+  LOGI("Out C2DTransform");
+}
+
+void C2DTranslate(Dart_NativeArguments arguments) {
+  LOGI("In C2DTranslate");
+  Dart_EnterScope();
+  int handle = GetArgAsInt(arguments, 0);
+  double x = GetArgAsDouble(arguments, 1);
+  double y = GetArgAsDouble(arguments, 2);
+  Context2D(handle)->Translate(x, y);
+  Dart_ExitScope();
+  LOGI("Out C2DTranslate");
+}
+
 struct FunctionLookup {
   const char* name;
   Dart_NativeFunction function;
@@ -911,6 +1531,8 @@
     {"SystemRand", SystemRand},
     {"SystemSrand", SystemSrand},
     {"SwapBuffers", SwapBuffers},
+    {"GetDeviceScreenWidth", GetDeviceScreenWidth},
+    {"GetDeviceScreenHeight", GetDeviceScreenHeight},
     {"GLAttachShader", GLAttachShader},
     {"GLBindBuffer", GLBindBuffer},
     {"GLBufferData", GLBufferData},
@@ -973,6 +1595,63 @@
     {"LoadSample", LoadSample},
     {"PlaySample", PlaySample},
 
+    // 2D Support
+
+    { "C2DCreateNativeContext", C2DCreateNativeContext},
+
+    // Property getters/setters.
+
+    { "C2DSetWidth", C2DSetWidth},
+    { "C2DSetHeight", C2DSetHeight},
+    { "C2DSetGlobalAlpha", C2DSetGlobalAlpha},
+    { "C2DSetFillStyle", C2DSetFillStyle},
+    { "C2DSetFont", C2DSetFont},
+    { "C2DSetGlobalCompositeOperation", C2DSetGlobalCompositeOperation},
+    { "C2DSetLineCap", C2DSetLineCap},
+    { "C2DSetLineJoin", C2DSetLineJoin},
+    { "C2DSetLineWidth", C2DSetLineWidth},
+    { "C2DSetMiterLimit", C2DSetMiterLimit},
+    { "C2DSetShadowBlur", C2DSetShadowBlur},
+    { "C2DSetShadowColor", C2DSetShadowColor},
+    { "C2DSetShadowOffsetX", C2DSetShadowOffsetX},
+    { "C2DSetShadowOffsetY", C2DSetShadowOffsetY},
+    { "C2DSetStrokeStyle", C2DSetStrokeStyle},
+    { "C2DSetTextAlign", C2DSetTextAlign},
+    { "C2DSetTextBaseline", C2DSetTextBaseline},
+    { "C2DGetImageSmoothingEnabled", C2DGetImageSmoothingEnabled},
+
+    // Methods.
+    { "C2DArc", C2DArc},
+    { "C2DArcTo", C2DArcTo},
+    { "C2DBeginPath", C2DBeginPath},
+    { "C2DBezierCurveTo", C2DBezierCurveTo},
+    { "C2DClearRect", C2DClearRect},
+    { "C2DClip", C2DClip},
+    { "C2DClosePath", C2DClosePath},
+    { "C2DCreateImageDataFromDimensions", C2DCreateImageDataFromDimensions},
+    { "C2DDrawImage", C2DDrawImage},
+    { "C2DFill", C2DFill},
+    { "C2DFillRect", C2DFillRect},
+    { "C2DFillText", C2DFillText},
+    { "C2DGetImageData", C2DGetImageData},
+    { "C2DLineTo", C2DLineTo},
+    { "C2DMeasureText", C2DMeasureText},
+    { "C2DMoveTo", C2DMoveTo},
+    { "C2DPutImageData", C2DPutImageData},
+    { "C2DQuadraticCurveTo", C2DQuadraticCurveTo},
+    { "C2DRect", C2DRect},
+    { "C2DRestore", C2DRestore},
+    { "C2DRotate", C2DRotate},
+    { "C2DSave", C2DSave},
+    { "C2DScale", C2DScale},
+    { "C2DSetLineDash", C2DSetLineDash},
+    { "C2DSetLineDashOffset", C2DSetLineDashOffset},
+    { "C2DSetTransform", C2DSetTransform},
+    { "C2DStroke", C2DStroke},
+    { "C2DStrokeRect", C2DStrokeRect},
+    { "C2DStrokeText", C2DStrokeText},
+    { "C2DTransform", C2DTransform},
+    { "C2DTranslate", C2DTranslate},
     {NULL, NULL}};
 
 Dart_NativeFunction ResolveName(Dart_Handle name, int argc) {
@@ -990,4 +1669,3 @@
   Dart_ExitScope();
   return result;
 }
-
diff --git a/runtime/embedders/openglui/common/extension.h b/runtime/embedders/openglui/common/extension.h
index 4825d90..a13413e 100644
--- a/runtime/embedders/openglui/common/extension.h
+++ b/runtime/embedders/openglui/common/extension.h
@@ -13,6 +13,8 @@
 extern void StopBackgroundSound();
 extern int32_t LoadSoundSample(const char* path);
 extern int32_t PlaySoundSample(const char* path);
+extern int32_t Init2DGraphics();
+
 
 #endif  // EMBEDDERS_OPENGLUI_COMMON_EXTENSION_H_
 
diff --git a/runtime/embedders/openglui/common/gl.dart b/runtime/embedders/openglui/common/gl.dart
index a916726..95c1d2b 100644
--- a/runtime/embedders/openglui/common/gl.dart
+++ b/runtime/embedders/openglui/common/gl.dart
@@ -4,11 +4,51 @@
 
 library android_extension;
 
+class CanvasElement {
+  int _height;
+  int _width;
+
+  get height => _height;
+  get width => _width;
+
+  CanvasRenderingContext2D _context2d;
+  WebGLRenderingContext _context3d;
+
+  CanvasElement({int width, int height}) {
+    _width = (width == null) ? getDeviceScreenWidth() : width;
+    _height = (height == null) ? getDeviceScreenHeight() : height;
+  }
+
+  CanvasRenderingContext getContext(String contextId) {
+    if (contextId == "2d") {
+      if (_context2d == null) {
+        _context2d = new CanvasRenderingContext2D(this, _width, _height);
+      }
+      return _context2d;
+    } else if (contextId == "webgl" || 
+               contextId == "experimental-webgl") {
+      if (_context3d == null) {
+        _context3d = new WebGLRenderingContext(this);
+      }
+      return _context3d;
+    }
+  }
+}
+
+class CanvasRenderingContext {
+  final CanvasElement canvas;
+
+  CanvasRenderingContext(this.canvas);
+}
+
 // The simplest way to call native code: top-level functions.
 int systemRand() native "SystemRand";
 void systemSrand(int seed) native "SystemSrand";
 void log(String what) native "Log";
 
+int getDeviceScreenWidth() native "GetDeviceScreenWidth";
+int getDeviceScreenHeight() native "GetDeviceScreenHeight";
+
 // EGL functions.
 void glSwapBuffers() native "SwapBuffers";
 
@@ -76,8 +116,8 @@
 String glGetShaderInfoLog(int shader) native "GLGetShaderInfoLog";
 String glGetProgramInfoLog(int program) native "GLGetProgramInfoLog";
 
-class WebGLRenderingContext {
-  WebGLRenderingContext();
+class WebGLRenderingContext extends CanvasRenderingContext {
+  WebGLRenderingContext(canvas) : super(canvas);
 
   static get ARRAY_BUFFER => glArrayBuffer();
   static get COLOR_BUFFER_BIT => glColorBufferBit();
@@ -156,8 +196,6 @@
   }
 }
 
-var gl = new WebGLRenderingContext();
-
 //------------------------------------------------------------------
 // Simple audio support.
 
@@ -184,3 +222,514 @@
   }
 }
 
+//------------------------------------------------------------------
+// 2D canvas support
+
+int C2DSetWidth(int handle, int width)
+    native "C2DSetWidth";
+int C2DSetHeight(int handle, int height)
+    native "C2DSetHeight";
+
+double C2DSetGlobalAlpha(int handle, double globalAlpha)
+    native "C2DSetGlobalAlpha";
+void C2DSetFillStyle(int handle, fs)
+    native "C2DSetFillStyle";
+String C2DSetFont(int handle, String font)
+    native "C2DSetFont";
+void C2DSetGlobalCompositeOperation(int handle, String op)
+    native "C2DSetGlobalCompositeOperation";
+C2DSetLineCap(int handle, String lc)
+    native "C2DSetLineCap";
+C2DSetLineJoin(int handle, String lj)
+    native "C2DSetLineJoin";
+C2DSetLineWidth(int handle, double w)
+    native "C2DSetLineWidth";
+C2DSetMiterLimit(int handle, double limit)
+    native "C2DSetMiterLimit";
+C2DSetShadowBlur(int handle, double blur)
+    native "C2DSetShadowBlur";
+C2DSetShadowColor(int handle, String color)
+    native "C2DSetShadowColor";
+C2DSetShadowOffsetX(int handle, double offset)
+    native "C2DSetShadowOffsetX";
+C2DSetShadowOffsetY(int handle, double offset)
+    native "C2DSetShadowOffsetY";
+void C2DSetStrokeStyle(int handle, ss)
+    native "C2DSetStrokeStyle";
+String C2DSetTextAlign(int handle, String align)
+    native "C2DSetTextAlign";
+String C2DSetTextBaseline(int handle, String baseline)
+    native "C2DSetTextBaseline";
+C2DGetBackingStorePixelRatio(int handle)
+    native "C2DGetBackingStorePixelRatio";
+void C2DSetImageSmoothingEnabled(int handle, bool ise)
+    native "C2DSetImageSmoothingEnabled";    
+void C2DSetLineDash(int handle, List v)
+    native "C2DSetLineDash";
+C2DSetLineDashOffset(int handle, int v)
+    native "C2DSetLineDashOffset";
+void C2DArc(int handle, double x, double y, double radius,
+    double startAngle, double endAngle, [bool anticlockwise = false])
+    native "C2DArc";
+void C2DArcTo(int handle, double x1, double y1,
+              double x2, double y2, double radius)
+    native "C2DArcTo"; 
+void C2DArcTo2(int handle, double x1, double y1,
+               double x2, double y2, double radiusX,
+    double radiusY, double rotation)
+    native "C2DArcTo2"; 
+void C2DBeginPath(int handle)
+    native "C2DBeginPath";
+void C2DBezierCurveTo(int handle, double cp1x, double cp1y,
+                      double cp2x, double cp2y, double x, double y)
+    native "C2DBezierCurveTo";
+void C2DClearRect(int handle, double x, double y, double w, double h)
+    native "C2DClearRect";
+void C2DClip(int handle)
+    native "C2DClip";
+void C2DClosePath(int handle)
+    native "C2DClosePath";
+ImageData C2DCreateImageDataFromDimensions(int handle, num w, num h)
+    native "C2DCreateImageDataFromDimensions";
+void C2DDrawImage(int handle, String src_url,
+                  int sx, int sy,
+                  bool has_src_dimensions, int sw, int sh,
+                  int dx, int dy,
+                  bool has_dst_dimensions, int dw, int dh)
+    native "C2DDrawImage";
+void C2DFill(int handle)
+    native "C2DFill";
+void C2DFillRect(int handle, double x, double y, double w, double h)
+    native "C2DFillRect";
+void C2DFillText(int handle, String text, double x, double y, double maxWidth)
+    native "C2DFillText";
+ImageData C2DGetImageData(num sx, num sy, num sw, num sh)
+    native "C2DGetImageData";    
+void C2DLineTo(int handle, double x, double y)
+    native "C2DLineTo";
+double C2DMeasureText(int handle, String text)
+    native "C2DMeasureText";
+void C2DMoveTo(int handle, double x, double y)
+    native "C2DMoveTo";
+void C2DPutImageData(int handle, ImageData imagedata, double dx, double dy)
+    native "C2DPutImageData";    
+void C2DQuadraticCurveTo(int handle, double cpx, double cpy, double x, double y)
+    native "C2DQuadraticCurveTo";
+void C2DRect(int handle, double x, double y, double w, double h)
+    native "C2DRect";
+void C2DRestore(int handle)
+    native "C2DRestore";
+void C2DRotate(int handle, double a)
+    native "C2DRotate";
+void C2DSave(int handle)
+    native "C2DSave";
+void C2DScale(int handle, double sx, double sy)
+    native "C2DScale";
+void C2DSetTransform(int handle, double m11, double m12,
+                     double m21, double m22, double dx, double dy)
+    native "C2DSetTransform";
+void C2DStroke(int handle)
+    native "C2DStroke";
+void C2DStrokeRect(int handle, double x, double y, double w, double h)
+    native "C2DStrokeRect";    
+void C2DStrokeText(int handle, String text, double x, double y, double maxWidth)
+    native "C2DStrokeText";
+void C2DTransform(int handle, double m11, double m12,
+                  double m21, double m22, double dx, double dy)
+    native "C2DTransform";
+void C2DTranslate(int handle, double x, double y)
+    native "C2DTranslate";
+
+void C2DCreateNativeContext(int handle, int width, int height)
+    native "C2DCreateNativeContext";
+
+class ElementEvents {
+  final List load;
+  ElementEvents()
+    : load =new List() {
+  }
+}
+
+class ImageElement {
+  ElementEvents on;
+  String _src;
+  int _width;
+  int _height;
+
+  get src => _src;
+  set src(String v) {
+    _src = v;
+    for (var e in on.load) {
+      e(this);
+    }
+  }
+
+  get width => _width;
+  set width(int widthp) => _width = widthp;
+
+  get height => _height;
+  set height(int heightp) => _height = heightp;
+
+  ImageElement({String srcp, int widthp, int heightp})
+    : on = new ElementEvents(),
+      _src = srcp,
+      _width = widthp,
+      _height = heightp {
+  }
+}
+
+class ImageData {
+  final Uint8ClampedArray data;
+  final int height;
+  final int width;
+  ImageData(this.height, this.width, this.data);
+}
+
+class TextMetrics {
+  final num width;
+  TextMetrics(this.width);
+}
+
+class CanvasRenderingContext2D extends CanvasRenderingContext {
+  // TODO(gram): We need to support multiple contexts, for cached content
+  // prerendered to an offscreen buffer. For this we will use handles, with
+  // handle 0 being the physical display.
+  static int _next_handle = 0;
+  int _handle = 0;
+
+  int _width, _height;
+  set width(int w) { _width = C2DSetWidth(_handle, w); }
+  get width => _width;
+  set height(int h) { _height = C2DSetHeight(_handle, h); }
+  get height => _height;
+
+  CanvasRenderingContext2D(canvas, width, height) : super(canvas) {
+    _width = width;
+    _height = height;
+    C2DCreateNativeContext(_handle = _next_handle++, width, height);
+  }
+
+  double _alpha = 1.0;
+  set globalAlpha(numa) {
+    _alpha = C2DSetGlobalAlpha(_handle, a.toDouble());
+  }
+  get globalAlpha => _alpha;
+
+  // TODO(gram): make sure we support compound assignments like:
+  // fillStyle = strokeStyle = "red"
+  var _fillStyle = "#000";
+  set fillStyle(fs) {
+    C2DSetFillStyle(_handle, _fillStyle = fs);
+  }
+  get fillStyle => _fillStyle;
+
+  String _font = "10px sans-serif";
+  set font(String f) { _font = C2DSetFont(_handle, f); }
+  get font => _font;
+
+  String _globalCompositeOperation = "source-over";
+  set globalCompositeOperation(String o) =>
+      C2DSetGlobalCompositeOperation(_handle, _globalCompositeOperation = o);
+  get globalCompositeOperation => _globalCompositeOperation;
+
+  String _lineCap = "butt"; // "butt", "round", "square"
+  get lineCap => _lineCap;
+  set lineCap(String lc) => C2DSetLineCap(_handle, _lineCap = lc);
+
+  int _lineDashOffset = 0;
+  get lineDashOffset => _lineDashOffset;
+  set lineDashOffset(num v) {
+    _lineDashOffset = v.toInt();
+    C2DSetLineDashOffset(_handle, _lineDashOffset);
+  }
+
+  String _lineJoin = "miter"; // "round", "bevel", "miter"
+  get lineJoin => _lineJoin;
+  set lineJoin(String lj) =>  C2DSetLineJoin(_handle, _lineJoin = lj);
+
+  num _lineWidth = 1.0;
+  get lineWidth => _lineWidth;
+  set lineWidth(num w) {
+    C2DSetLineWidth(_handle, w.toDouble());
+    _lineWidth = w;
+  }
+
+  num _miterLimit = 10.0; // (default 10)
+  get miterLimit => _miterLimit;
+  set miterLimit(num limit) {
+    C2DSetMiterLimit(_handle, limit.toDouble());
+    _miterLimit = limit;
+  }
+
+  num _shadowBlur;
+  get shadowBlur =>  _shadowBlur;
+  set shadowBlur(num blur) {
+    _shadowBlur = blur;
+    C2DSetShadowBlur(_handle, blur.toDouble());
+  }
+
+  String _shadowColor;
+  get shadowColor => _shadowColor;
+  set shadowColor(String color) =>
+      C2DSetShadowColor(_handle, _shadowColor = color);
+  
+  num _shadowOffsetX;
+  get shadowOffsetX => _shadowOffsetX;
+  set shadowOffsetX(num offset) {
+    _shadowOffsetX = offset;
+    C2DSetShadowOffsetX(_handle, offset.toDouble());
+  }
+
+  num _shadowOffsetY;
+  get shadowOffsetY => _shadowOffsetY;
+  set shadowOffsetY(num offset) {
+    _shadowOffsetY = offset;
+    C2DSetShadowOffsetY(_handle, offset.toDouble());
+  }
+
+  var _strokeStyle = "#000";
+  get strokeStyle => _strokeStyle;
+  set strokeStyle(ss) {
+    C2DSetStrokeStyle(_handle, _strokeStyle = ss);
+  }
+
+  String _textAlign = "start";
+  get textAlign => _textAlign;
+  set textAlign(String a) { _textAlign = C2DSetTextAlign(_handle, a); }
+
+  String _textBaseline = "alphabetic";
+  get textBaseline => _textBaseline;
+  set textBaseline(String b) { _textBaseline = C2DSetTextBaseline(_handle, b); }
+
+  get webkitBackingStorePixelRatio => C2DGetBackingStorePixelRatio(_handle);
+
+  bool _webkitImageSmoothingEnabled;
+  get webkitImageSmoothingEnabled => _webkitImageSmoothingEnabled;
+  set webkitImageSmoothingEnabled(bool v) =>
+     C2DSetImageSmoothingEnabled(_webkitImageSmoothingEnabled = v);
+
+  get webkitLineDash => lineDash;
+  set webkitLineDash(List v) => lineDash = v;
+
+  get webkitLineDashOffset => lineDashOffset;
+  set webkitLineDashOffset(num v) => lineDashOffset = v;
+
+  // Methods
+
+  void arc(num x, num y, num radius, num a1, num a2, bool anticlockwise) {
+    if (radius < 0) {
+      // throw IndexSizeError
+    } else {
+      C2DArc(_handle, x.toDouble(), y.toDouble(), radius.toDouble(), a1.toDouble(), a2.toDouble(), anticlockwise);
+    }
+  }
+
+  // Note - looking at the Dart docs it seems Dart doesn't support
+  // the second form in the browser.
+  void arcTo(num x1, num y1, num x2, num y2,
+    num radiusX, [num radiusY, num rotation]) {
+    if (radiusY == null) {
+      C2DArcTo(_handle, x1.toDouble(), y1.toDouble(),
+                        x2.toDouble(), y2.toDouble(), radiusX.toDouble());
+    } else {
+      C2DArcTo2(_handle, x1.toDouble(), y1.toDouble(),
+                         x2.toDouble(), y2.toDouble(),
+                         radiusX.toDouble(), radiusY.toDouble(),
+                         rotation.toDouble());
+    }
+  }
+
+  void beginPath() => C2DBeginPath(_handle);
+
+  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y,
+    num x, num y) =>
+    C2DBezierCurveTo(_handle, cp1x.toDouble(), cp1y.toDouble(),
+                              cp2x.toDouble(), cp2y.toDouble(),
+                              x.toDouble(), y.toDouble());
+
+  void clearRect(num x, num y, num w, num h) =>
+    C2DClearRect(_handle, x.toDouble(), y.toDouble(), w.toDouble(), h.toDouble());
+
+  void clip() => C2DClip(_handle);
+
+  void closePath() => C2DClosePath(_handle);
+
+  ImageData createImageData(var imagedata_OR_sw, [num sh = null]) {
+    if (sh == null) {
+      throw new Exception('Unimplemented createImageData(imagedata)');
+    } else {
+      return C2DCreateImageDataFromDimensions(_handle, imagedata_OR_sw, sh);
+    }
+  }
+
+  CanvasGradient createLinearGradient(num x0, num y0, num x1, num y1) {
+    throw new Exception('Unimplemented createLinearGradient');
+  }
+
+  CanvasPattern createPattern(canvas_OR_image, String repetitionType) {
+    throw new Exception('Unimplemented createPattern');
+  }
+
+  CanvasGradient createRadialGradient(num x0, num y0, num x1, num y1, num r1) {
+    throw new Exception('Unimplemented createRadialGradient');
+  }
+
+  void drawImage(ImageElement image, num x1, num y1,
+                [num w1, num h1, num x2, num y2, num w2, num h2]) {
+    var w = (image.width == null) ? 0 : image.width;
+    var h = (image.height == null) ?  0 : image.height;
+    if (!?w1) { // drawImage(image, dx, dy)
+      C2DDrawImage(_handle, image.src, 0, 0, false, w, h,
+                   x1.toInt(), y1.toInt(), false, 0, 0);
+    } else if (!?x2) {  // drawImage(image, dx, dy, dw, dh)
+      C2DDrawImage(_handle, image.src, 0, 0, false, w, h,
+                   x1.toInt(), y1.toInt(), true, w1.toInt(), h1.toInt());
+    } else {  // drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
+      C2DDrawImage(_handle, image.src, 
+                   x1.toInt(), y1.toInt(), true, w1.toInt(), h1.toInt(),
+                   x2.toInt(), y2.toInt(), true, w2.toInt(), h2.toInt());
+    }
+  }
+
+  void fill() => C2DFill(_handle);
+
+  void fillRect(num x, num y, num w, num h) =>
+    C2DFillRect(_handle, x.toDouble(), y.toDouble(),
+                         w.toDouble(), h.toDouble());
+
+  void fillText(String text, num x, num y, [num maxWidth = -1]) =>
+      C2DFillText(_handle, text, x.toDouble(), y.toDouble(),
+                                 maxWidth.toDouble());
+
+  ImageData getImageData(num sx, num sy, num sw, num sh) =>
+    C2DGetImageData(sx, sy, sw, sh);
+
+  List<double> _lineDash = null;
+  List<num> getLineDash() {
+    if (_lineDash == null) return [];
+    return _lineDash;  // TODO(gram): should we return a copy?
+  }
+
+  bool isPointInPath(num x, num y) {
+    throw new Exception('Unimplemented isPointInPath');
+  }
+
+  void lineTo(num x, num y) {
+    C2DLineTo(_handle, x.toDouble(), y.toDouble());
+  }
+
+  TextMetrics measureText(String text) {
+    double w = C2DMeasureText(_handle, text);
+    return new TextMetrics(w);
+  }
+
+  void moveTo(num x, num y) =>
+    C2DMoveTo(_handle, x.toDouble(), y.toDouble());
+
+  void putImageData(ImageData imagedata, num dx, num dy,
+                   [num dirtyX, num dirtyY, num dirtyWidth, num dirtyHeight]) {
+    if (dirtyX != null || dirtyY != null) {
+      throw new Exception('Unimplemented putImageData');
+    } else {
+      C2DPutImageData(_handle, imagedata, dx, dy);
+    }
+  }
+
+  void quadraticCurveTo(num cpx, num cpy, num x, num y) =>
+    C2DQuadraticCurveTo(_handle, cpx.toDouble(), cpy.toDouble(),
+                        x.toDouble(), y.toDouble());
+
+  void rect(num x, num y, num w, num h) =>
+    C2DRect(_handle, x.toDouble(), y.toDouble(), w.toDouble(), h.toDouble());
+
+  void restore() => C2DRestore(_handle);
+
+  void rotate(num angle) => C2DRotate(_handle, angle.toDouble());
+
+  void save() => C2DSave(_handle);
+
+  void scale(num x, num y) => C2DScale(_handle, x.toDouble(), y.toDouble());
+
+  void setFillColorHsl(int h, num s, num l, [num a = 1]) {
+    throw new Exception('Unimplemented setFillColorHsl');
+  }
+
+  void setFillColorRgb(int r, int g, int b, [num a = 1]) {
+    throw new Exception('Unimplemented setFillColorRgb');
+  }
+
+  void setLineDash(List<num> dash) {
+    var valid = true;
+    var new_dash;
+    if (dash.length % 2 == 1) {
+      new_dash = new List<double>(2 * dash.length);
+      for (int i = 0; i < dash.length; i++) {
+        double v = dash[i].toDouble();
+        if (v < 0) {
+          valid = false;
+          break;
+        }
+        new_dash[i] = new_dash[i + dash.length] = v;
+      }
+    } else {
+      new_dash = new List<double>(dash.length);
+      for (int i = 0; i < dash.length; i++) {
+        double v = dash[i].toDouble();
+        if (v < 0) {
+          valid = false;
+          break;
+        }
+        new_dash[i] = v;
+      }
+    }
+    if (valid) {
+      C2DSetLineDash(_handle, _lineDash = new_dash);
+    }
+  }
+
+  void setStrokeColorHsl(int h, num s, num l, [num a = 1]) {
+    throw new Exception('Unimplemented setStrokeColorHsl');
+  }
+
+  void setStrokeColorRgb(int r, int g, int b, [num a = 1]) {
+    throw new Exception('Unimplemented setStrokeColorRgb');
+  }
+
+  void setTransform(num m11, num m12, num m21, num m22, num dx, num dy) =>
+          C2DSetTransform(_handle, m11.toDouble(), m12.toDouble(),
+                                   m21.toDouble(), m22.toDouble(),
+                                   dx.toDouble(), dy.toDouble());
+
+  void stroke() => C2DStroke(_handle);
+
+  void strokeRect(num x, num y, num w, num h, [num lineWidth]) =>
+    C2DStrokeRect(_handle, x.toDouble(), y.toDouble(), w.toDouble(), h.toDouble());
+
+  void strokeText(String text, num x, num y, [num maxWidth = -1]) =>
+      C2DStrokeText(_handle, text, x.toDouble(), y.toDouble(),
+                                 maxWidth.toDouble());
+
+  void transform(num m11, num m12, num m21, num m22, num dx, num dy) =>
+          C2DTransform(_handle, m11.toDouble(), m12.toDouble(),
+                       m21.toDouble(), m22.toDouble(),
+                       dx.toDouble(), dy.toDouble());
+
+  void translate(num x, num y) =>
+      C2DTranslate(_handle, x.toDouble(), y.toDouble());
+
+  ImageData webkitGetImageDataHD(num sx, num sy, num sw, num sh) {
+    throw new Exception('Unimplemented webkitGetImageDataHD');
+  }
+
+  void webkitPutImageDataHD(ImageData imagedata, num dx, num dy,
+                           [num dirtyX, num dirtyY,
+                            num dirtyWidth, num dirtyHeight]) {
+    throw new Exception('Unimplemented webkitGetImageDataHD');
+  }
+
+  // TODO(vsm): Kill.
+  noSuchMethod(invocation) {
+      throw new Exception('Unimplemented/unknown ${invocation.memberName}');
+  }
+}
+
diff --git a/runtime/embedders/openglui/common/gl_graphics_handler.cc b/runtime/embedders/openglui/common/gl_graphics_handler.cc
deleted file mode 100644
index 5208b06..0000000
--- a/runtime/embedders/openglui/common/gl_graphics_handler.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-// 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.
-
-#include "embedders/openglui/common/gl_graphics_handler.h"
-#include "embedders/openglui/common/log.h"
-
-extern void CheckGLError(const char *function);
-
-void GLGraphicsHandler::SetViewport(int left, int top, int width, int height) {
-  glViewport(left, top, width, height);
-  CheckGLError("glViewPort");
-}
-
-int GLGraphicsHandler::BuildProgram(const char* vertexShaderSource,
-                                 const char* fragmentShaderSource) const {
-  int vertexShader = BuildShader(vertexShaderSource, GL_VERTEX_SHADER);
-  int fragmentShader = BuildShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
-  if (vertexShader < 0 || fragmentShader < 0) {
-    return -1;
-  }
-
-  GLuint programHandle = glCreateProgram();
-  glAttachShader(programHandle, static_cast<GLuint>(vertexShader));
-  glAttachShader(programHandle, static_cast<GLuint>(fragmentShader));
-  glLinkProgram(programHandle);
-
-  GLint linkSuccess;
-  glGetProgramiv(programHandle, GL_LINK_STATUS, &linkSuccess);
-  if (linkSuccess == GL_FALSE) {
-    GLint infoLogLength;
-    glGetProgramiv(programHandle, GL_INFO_LOG_LENGTH, &infoLogLength);
-    GLchar* strInfoLog = new GLchar[infoLogLength + 1];
-    glGetProgramInfoLog(programHandle, infoLogLength, NULL, strInfoLog);
-    strInfoLog[infoLogLength] = 0;
-    LOGE("Link failed: %s", strInfoLog);
-    delete[] strInfoLog;
-    return -1;
-  }
-  return static_cast<int>(programHandle);
-}
-
-int GLGraphicsHandler::BuildShader(const char* source,
-                                   GLenum shaderType) const {
-  GLuint shaderHandle = glCreateShader(shaderType);
-  glShaderSource(shaderHandle, 1, &source, NULL);
-  glCompileShader(shaderHandle);
-
-  GLint compileSuccess;
-  glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &compileSuccess);
-
-  if (compileSuccess == GL_FALSE) {
-    GLint infoLogLength = 0;
-    glGetShaderiv(shaderHandle, GL_INFO_LOG_LENGTH, &infoLogLength);
-    GLchar* strInfoLog = new GLchar[infoLogLength + 1];
-    glGetShaderInfoLog(shaderHandle, infoLogLength, NULL, strInfoLog);
-    strInfoLog[infoLogLength] = 0;
-    LOGE("Shader compile failed: %s", strInfoLog);
-    delete [] strInfoLog;
-    return -1;
-  }
-  return static_cast<int>(shaderHandle);
-}
-
diff --git a/runtime/embedders/openglui/common/gl_graphics_handler.h b/runtime/embedders/openglui/common/gl_graphics_handler.h
deleted file mode 100644
index ca8b54f..0000000
--- a/runtime/embedders/openglui/common/gl_graphics_handler.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// 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.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_GL_GRAPHICS_HANDLER_H_
-#define EMBEDDERS_OPENGLUI_COMMON_GL_GRAPHICS_HANDLER_H_
-
-#include "embedders/openglui/common/graphics_handler.h"
-#include "embedders/openglui/common/opengl.h"
-#include "embedders/openglui/common/timer.h"
-
-class GLGraphicsHandler : public GraphicsHandler {
-  public:
-    GLGraphicsHandler()
-      : GraphicsHandler() {
-    }
-
-    virtual int32_t Start() = 0;
-    virtual void Stop() = 0;
-
-    void SwapBuffers() {
-      GLSwapBuffers();
-    }
-
-    virtual int32_t Update() {
-      SwapBuffers();
-      return 0;
-    }
-
-    void SetViewport(int left, int top, int width, int height);
-    int BuildProgram(const char* vertexShaderSource,
-                     const char* fragmentShaderSource) const;
-    int BuildShader(const char* source, GLenum shaderType) const;
-
-    virtual ~GLGraphicsHandler() {
-    }
-};
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_GL_GRAPHICS_HANDLER_H_
-
diff --git a/runtime/embedders/openglui/common/graphics_handler.cc b/runtime/embedders/openglui/common/graphics_handler.cc
new file mode 100644
index 0000000..05615f0
--- /dev/null
+++ b/runtime/embedders/openglui/common/graphics_handler.cc
@@ -0,0 +1,81 @@
+// 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.
+
+#include "embedders/openglui/common/graphics_handler.h"
+#include "embedders/openglui/common/canvas_context.h"
+#include "embedders/openglui/common/log.h"
+
+extern void CheckGLError(const char *function);
+
+GraphicsHandler* graphics;
+
+GraphicsHandler::GraphicsHandler()
+  : ag(),
+    grcontext(NULL),
+    width_(0),
+    height_(0) {
+  graphics = this;
+}
+
+// Kludge to get around an issue with Android emulator, which returns
+// NULL for the shader language version, causing Skia to blow up.
+const GrGLubyte* myGLGetString(GLenum name) {
+  const GrGLubyte* str = glGetString(name);
+  if (NULL == str && GL_SHADING_LANGUAGE_VERSION == name) {
+    return reinterpret_cast<GrGLubyte*>(
+        const_cast<char*>("OpenGL ES GLSL ES 1.0"));
+  } else {
+    return str;
+  }
+}
+
+int32_t GraphicsHandler::Start() {
+  SkGraphics::Init();
+  GrGLInterface* fGL = const_cast<GrGLInterface*>(GrGLCreateNativeInterface());
+  LOGI("Created native interface %s\n", fGL ? "succeeded" : "failed");
+  fGL->fGetString = myGLGetString;
+  grcontext = GrContext::Create(kOpenGL_Shaders_GrEngine,
+                        (GrPlatform3DContext)fGL);
+  LOGI("Created GrContext %s\n", grcontext ? "succeeded" : "failed");
+  return 0;
+}
+
+void GraphicsHandler::Stop() {
+  SkGraphics::Term();
+}
+
+SkCanvas* GraphicsHandler::CreateCanvas() {
+  GrPlatformRenderTargetDesc desc;
+  desc.fWidth = width_;
+  desc.fHeight = height_;
+  desc.fConfig = kSkia8888_PM_GrPixelConfig;
+  glGetIntegerv(GL_SAMPLES, &desc.fSampleCnt);
+  glGetIntegerv(GL_STENCIL_BITS, &desc.fStencilBits);
+  GrGLint buffer;
+  glGetIntegerv(GL_FRAMEBUFFER_BINDING, &buffer);
+  desc.fRenderTargetHandle = buffer;
+  GrRenderTarget* fGrRenderTarget = grcontext->createPlatformRenderTarget(desc);
+  return new SkCanvas(new SkGpuDevice(grcontext, fGrRenderTarget));
+}
+
+void GraphicsHandler::SetViewport(int left, int top, int width, int height) {
+  width_ = width;
+  height_ = height;
+  glViewport(left, top, width, height);
+  CheckGLError("glViewPort");
+}
+
+int32_t GraphicsHandler::Update() {
+  extern CanvasContext* display_context;
+  if (display_context != NULL) {
+    LOGI("Flushing display context\n");
+    display_context->Flush();
+  }
+  SwapBuffers();
+  return 0;
+}
+
+
+
+
diff --git a/runtime/embedders/openglui/common/graphics_handler.h b/runtime/embedders/openglui/common/graphics_handler.h
index 1d02089..ba82adc 100644
--- a/runtime/embedders/openglui/common/graphics_handler.h
+++ b/runtime/embedders/openglui/common/graphics_handler.h
@@ -5,17 +5,14 @@
 #ifndef EMBEDDERS_OPENGLUI_COMMON_GRAPHICS_HANDLER_H_
 #define EMBEDDERS_OPENGLUI_COMMON_GRAPHICS_HANDLER_H_
 
-#include <stdint.h>
-
 #include "embedders/openglui/common/isized.h"
+#include "embedders/openglui/common/opengl.h"
+#include "embedders/openglui/common/support.h"
 #include "embedders/openglui/common/timer.h"
 
 class GraphicsHandler : public ISized {
   public:
-    GraphicsHandler()
-      : width_(0),
-        height_(0) {
-    }
+    GraphicsHandler();
 
     const int32_t& height() {
       return height_;
@@ -25,23 +22,37 @@
       return width_;
     }
 
-    virtual int32_t Start() = 0;
-    virtual void Stop() = 0;
+    void ApplyOrtho(float maxX, float maxY) const;
+    void ApplyRotation(float degrees) const;
 
-    virtual void SwapBuffers() = 0;
+    virtual int32_t Start();
+    virtual void Stop();
 
-    virtual int32_t Update() {
-      return 0;
+    void SwapBuffers() {
+      GLSwapBuffers();
     }
 
-    virtual void SetViewport(int left, int top, int width, int height) = 0;
+    virtual int32_t Update();
+
+    void SetViewport(int left, int top, int width, int height);
+
+    SkCanvas* CreateCanvas();
+
+    void Flush() {
+      // TODO(gram): see if we really need this.
+      grcontext->flush();
+    }
 
     virtual ~GraphicsHandler() {
     }
 
   protected:
+    SkAutoGraphics ag;
+    GrContext* grcontext;
     int32_t width_, height_;
 };
 
+extern GraphicsHandler* graphics;
+
 #endif  // EMBEDDERS_OPENGLUI_COMMON_GRAPHICS_HANDLER_H_
 
diff --git a/runtime/embedders/openglui/common/isized.h b/runtime/embedders/openglui/common/isized.h
index c29ba93..b84dde2 100644
--- a/runtime/embedders/openglui/common/isized.h
+++ b/runtime/embedders/openglui/common/isized.h
@@ -5,6 +5,8 @@
 #ifndef EMBEDDERS_OPENGLUI_COMMON_ISIZED_H_
 #define EMBEDDERS_OPENGLUI_COMMON_ISIZED_H_
 
+#include <stdint.h>
+
 // An interface for objects that have a size. VMGlue needs the window
 // size when calling setup() (and eventually resize()) but it does not
 // need to know anything else about the window, so we use this interface.
diff --git a/runtime/embedders/openglui/common/opengl.h b/runtime/embedders/openglui/common/opengl.h
index ac7b485..fb844fe 100644
--- a/runtime/embedders/openglui/common/opengl.h
+++ b/runtime/embedders/openglui/common/opengl.h
@@ -39,5 +39,17 @@
 #  define GLSwapBuffers()    glutSwapBuffers()
 #endif
 
+#include "core/SkCanvas.h"
+#include "core/SkGraphics.h"
+#include "core/SkPaint.h"
+#include "effects/SkBlurDrawLooper.h"
+#include "effects/SkDashPathEffect.h"
+#include "gpu/SkGpuDevice.h"
+#include "gpu/GrContext.h"
+#include "gpu/GrRenderTarget.h"
+#include "gpu/gl/GrGLInterface.h"
+#include "gpu/gl/SkNativeGLContext.h"
+#include "images/SkImageDecoder.h"
+
 #endif  // EMBEDDERS_OPENGLUI_COMMON_OPENGL_H_
 
diff --git a/runtime/embedders/openglui/common/sound_handler.cc b/runtime/embedders/openglui/common/sound_handler.cc
index 1412b7f..06c902f 100644
--- a/runtime/embedders/openglui/common/sound_handler.cc
+++ b/runtime/embedders/openglui/common/sound_handler.cc
@@ -33,7 +33,6 @@
   return sample;
 }
 
-
 int32_t PlayBackgroundSound(const char* path) {
   return SoundHandler::instance()->PlayBackground(path);
 }
diff --git a/runtime/embedders/openglui/common/support.h b/runtime/embedders/openglui/common/support.h
new file mode 100644
index 0000000..143c9a9
--- /dev/null
+++ b/runtime/embedders/openglui/common/support.h
@@ -0,0 +1,37 @@
+// 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.
+
+#ifndef EMBEDDERS_OPENGLUI_COMMON_SUPPORT_H_
+#define EMBEDDERS_OPENGLUI_COMMON_SUPPORT_H_
+
+#include "embedders/openglui/common/opengl.h"
+
+#ifndef MAX
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+#ifndef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+// Colors as used by canvas.
+typedef struct ColorRGBA {
+  // We store Skia-compatible values. Skia uses
+  // the form AARRGGBB.
+  uint32_t v;
+
+  inline ColorRGBA(char rp, char gp, char bp, char ap = 255) {
+    v = ((static_cast<uint32_t>(rp) & 0xFF) << 16) |
+        ((static_cast<uint32_t>(gp) & 0xFF) << 8) |
+        ((static_cast<uint32_t>(bp) & 0xFF) << 0) |
+        ((static_cast<uint32_t>(ap) & 0xFF) << 24);
+  }
+  inline ColorRGBA(uint32_t vp)
+    : v(vp) {
+  }
+  inline uint8_t alpha() {
+    return (v >> 24) & 0xFF;
+  }
+} ColorRGBA;
+
+#endif  // EMBEDDERS_OPENGLUI_COMMON_SUPPORT_H_
diff --git a/runtime/embedders/openglui/common/timer.cc b/runtime/embedders/openglui/common/timer.cc
index f5c1e0f..9a0e2af 100644
--- a/runtime/embedders/openglui/common/timer.cc
+++ b/runtime/embedders/openglui/common/timer.cc
@@ -43,24 +43,24 @@
 Timer::Timer() : elapsed_(0.0f), last_time_(0.0) {
 }
 
-void Timer::reset() {
+void Timer::Reset() {
   elapsed_ = 0.0f;
-  last_time_ = now();
+  last_time_ = Now();
 }
 
-void Timer::update() {
-  double current = now();
+void Timer::Update() {
+  double current = Now();
   elapsed_ = (current - last_time_);
   last_time_ = current;
 }
 
-double Timer::now() {
+double Timer::Now() {
   timespec timeval;
   clock_gettime(CLOCK_MONOTONIC, &timeval);
   return timeval.tv_sec + (timeval.tv_nsec * NANO);
 }
 
-float Timer::elapsed() {
+float Timer::Elapsed() {
   return elapsed_;
 }
 
diff --git a/runtime/embedders/openglui/common/timer.h b/runtime/embedders/openglui/common/timer.h
index db7f50a..d2f3d67 100644
--- a/runtime/embedders/openglui/common/timer.h
+++ b/runtime/embedders/openglui/common/timer.h
@@ -10,10 +10,10 @@
 class Timer {
  public:
   Timer();
-  void reset();
-  void update();
-  double now();
-  float elapsed();
+  void Reset();
+  void Update();
+  double Now();
+  float Elapsed();
 
  private:
   float elapsed_;
diff --git a/runtime/embedders/openglui/common/vm_glue.cc b/runtime/embedders/openglui/common/vm_glue.cc
index b0a82bd..b5e33e0 100644
--- a/runtime/embedders/openglui/common/vm_glue.cc
+++ b/runtime/embedders/openglui/common/vm_glue.cc
@@ -43,17 +43,6 @@
   snprintf(extension_script_, len, "%s/%s", script_path, extension_script);
 }
 
-int VMGlue::ErrorExit(const char* format, ...) {
-  va_list arguments;
-  va_start(arguments, format);
-  LOGE(format, arguments);
-  va_end(arguments);
-  Dart_ExitScope();
-  Dart_ShutdownIsolate();
-  LOGE("Shutdown isolate");
-  return -1;
-}
-
 Dart_Handle VMGlue::CheckError(Dart_Handle handle) {
   if (Dart_IsError(handle)) {
     LOGE("Unexpected Error Handle: %s", Dart_GetError(handle));
@@ -129,8 +118,9 @@
 
 const char* VM_FLAGS[] = {
   "--enable_type_checks",  // TODO(gram): This should be an option!
-  "--trace_isolates",
-  "--trace_natives",
+  // "--trace_isolates",
+  // "--trace_natives",
+  // "--trace_compiler",
 };
 
 int VMGlue::InitializeVM() {
@@ -211,13 +201,14 @@
 int VMGlue::CallSetup() {
   if (!initialized_script_) {
     initialized_script_ = true;
-    LOGI("Invoking setup(0,0,%d,%d)", surface_->width(), surface_->height());
+    LOGI("Invoking setup(NULL, %d,%d)", surface_->width(), surface_->height());
     Dart_EnterIsolate(isolate_);
     Dart_EnterScope();
-    Dart_Handle args[2];
-    args[0] = CheckError(Dart_NewInteger(surface_->width()));
-    args[1] = CheckError(Dart_NewInteger(surface_->height()));
-    int rtn = Invoke("setup", 2, args);
+    Dart_Handle args[3];
+    args[0] = CheckError(Dart_Null());
+    args[1] = CheckError(Dart_NewInteger(surface_->width()));
+    args[2] = CheckError(Dart_NewInteger(surface_->height()));
+    int rtn = Invoke("setup", 3, args);
 
     if (rtn == 0) {
       // Plug in the print handler. It would be nice if we could do this
@@ -232,7 +223,6 @@
       CheckError(Dart_SetField(corelib,
         Dart_NewStringFromCString("_printClosure"), print));
     }
-
     Dart_ExitScope();
     Dart_ExitIsolate();
     LOGI("Done setup");
@@ -305,7 +295,8 @@
   LOGI("looking up the root library");
   Dart_Handle library = Dart_RootLibrary();
   if (Dart_IsNull(library)) {
-     return ErrorExit("Unable to find root library\n");
+     LOGE("Unable to find root library\n");
+     return -1;
   }
 
   Dart_Handle nameHandle = Dart_NewStringFromCString(function);
@@ -314,10 +305,10 @@
   Dart_Handle result = Dart_Invoke(library, nameHandle, argc, args);
 
   if (Dart_IsError(result)) {
+    const char* error = Dart_GetError(result);
+    LOGE("Invoke %s failed: %s", function, error);
     if (failIfNotDefined) {
-      return ErrorExit("Invoke %s: %s\n", function, Dart_GetError(result));
-    } else {
-      LOGE("Invoke %s: %s", function, Dart_GetError(result));
+      return -1;
     }
   }
 
@@ -326,7 +317,8 @@
   LOGI("Entering Dart message loop");
   result = Dart_RunLoop();
   if (Dart_IsError(result)) {
-    return ErrorExit("Dart_RunLoop: %s\n", Dart_GetError(result));
+    LOGE("Dart_RunLoop: %s\n", Dart_GetError(result));
+    return -1;
   }
 
   LOGI("out invoke");
diff --git a/runtime/embedders/openglui/common/vm_glue.h b/runtime/embedders/openglui/common/vm_glue.h
index 7efa02e..fc353a6 100644
--- a/runtime/embedders/openglui/common/vm_glue.h
+++ b/runtime/embedders/openglui/common/vm_glue.h
@@ -36,7 +36,6 @@
   int Invoke(const char *function, int argc, Dart_Handle* args,
              bool failIfNotDefined = true);
 
-  static int ErrorExit(const char* format, ...);
   static Dart_Handle CheckError(Dart_Handle);
 
   static bool CreateIsolateAndSetupHelper(const char* script_uri,
diff --git a/runtime/embedders/openglui/emulator/emulator_embedder.cc b/runtime/embedders/openglui/emulator/emulator_embedder.cc
index 371de7b..4f53b42 100644
--- a/runtime/embedders/openglui/emulator/emulator_embedder.cc
+++ b/runtime/embedders/openglui/emulator/emulator_embedder.cc
@@ -5,7 +5,8 @@
 #include "embedders/openglui/emulator/emulator_embedder.h"
 
 #include <string.h>
-
+#include <sys/time.h>
+#include "embedders/openglui/common/canvas_context.h"
 #include "embedders/openglui/common/context.h"
 #include "embedders/openglui/common/dart_host.h"
 #include "embedders/openglui/common/events.h"
@@ -17,27 +18,44 @@
 InputHandler* input_handler_ptr;
 LifeCycleHandler* lifecycle_handler_ptr;
 
+struct timeval tvStart;
+void tick(int data);
+
 void display() {
-    glClearColor(1.0, 1.0, 1.0, 1.0);
-    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-    lifecycle_handler_ptr->OnStep();
-    glutSwapBuffers();
+  // Get number of msecs since last call.
+  struct timeval tvEnd;
+  gettimeofday(&tvEnd, NULL);
+  uint64_t elapsed = (tvEnd.tv_usec + 1000000 * tvEnd.tv_sec) -
+                 (tvStart.tv_usec + 1000000 * tvStart.tv_sec);
+
+  if (lifecycle_handler_ptr->OnStep() != 0) {
+    exit(-1);
+  }
+  // Schedule next call, trying to aim for 60fps.
+  int delay = 1000 / 60 - (elapsed / 1000);
+  if (delay < 0) delay = 0;
+  tvStart = tvEnd;
+  glutTimerFunc(delay, tick, 0);
+}
+
+void tick(int data) {
+  display();
 }
 
 void reshape(int width, int height) {
-    glViewport(0, 0, width, height);
-    glMatrixMode(GL_PROJECTION);
-    glLoadIdentity();
-    glOrtho(0, width, 0, height, -1, 1);
-    glMatrixMode(GL_MODELVIEW);
-    glutPostRedisplay();
+  glViewport(0, 0, width, height);
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  glOrtho(0, width, 0, height, -1, 1);
+  glMatrixMode(GL_MODELVIEW);
+  glutPostRedisplay();
 }
 
 void keyboard(unsigned char key, int x, int y) {
   input_handler_ptr->OnKeyEvent(kKeyDown, time(0), 0, key, 0, 0);
   input_handler_ptr->OnKeyEvent(kKeyUp, time(0), 0, key, 0, 0);
   if (key == 27) {
-      exit(0);
+    exit(0);
   }
 }
 
@@ -63,11 +81,12 @@
   app_context.vm_glue = &vm_glue;
   DartHost host(&app_context);
   lifecycle_handler_ptr = &host;
-  lifecycle_handler_ptr->OnActivate();
   glutReshapeFunc(reshape);
   glutDisplayFunc(display);
   glutKeyboardFunc(keyboard);
-  glutIdleFunc(display);
+  lifecycle_handler_ptr->OnActivate();
+  gettimeofday(&tvStart, NULL);
+  glutTimerFunc(1, tick, 0);
   glutMainLoop();
 }
 
diff --git a/runtime/embedders/openglui/emulator/emulator_graphics_handler.cc b/runtime/embedders/openglui/emulator/emulator_graphics_handler.cc
index e1a5ae0..b552813 100644
--- a/runtime/embedders/openglui/emulator/emulator_graphics_handler.cc
+++ b/runtime/embedders/openglui/emulator/emulator_graphics_handler.cc
@@ -9,10 +9,9 @@
 
 EmulatorGraphicsHandler::EmulatorGraphicsHandler(int argc,
                                                  char** argv)
-  : GLGraphicsHandler() {
+  : GraphicsHandler() {
   glutInit(&argc, argv);
-  width_ = 480;
-  height_ = 800;
+  SetViewport(0, 0, 480, 800);
   for (int i = 1; i < argc; i++) {
     if (argv[i][0] == '-') {
       int next_arg = i + 1;
@@ -23,16 +22,17 @@
       }
     }
   }
+  glutInitWindowSize(width_, height_);
+  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_STENCIL);
+  glutCreateWindow("Dart");
 }
 
 int32_t EmulatorGraphicsHandler::Start() {
-  glutInitWindowSize(width_, height_);
-  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
-  glutCreateWindow("Dart");
-  return 0;
+  return GraphicsHandler::Start();
 }
 
 void EmulatorGraphicsHandler::Stop() {
+  GraphicsHandler::Stop();
   exit(0);
 }
 
diff --git a/runtime/embedders/openglui/emulator/emulator_graphics_handler.h b/runtime/embedders/openglui/emulator/emulator_graphics_handler.h
index c7dcdaa..4a29270 100644
--- a/runtime/embedders/openglui/emulator/emulator_graphics_handler.h
+++ b/runtime/embedders/openglui/emulator/emulator_graphics_handler.h
@@ -5,9 +5,9 @@
 #ifndef EMBEDDERS_OPENGLUI_EMULATOR_EMULATOR_GRAPHICS_HANDLER_H_
 #define EMBEDDERS_OPENGLUI_EMULATOR_EMULATOR_GRAPHICS_HANDLER_H_
 
-#include "embedders/openglui/common/gl_graphics_handler.h"
+#include "embedders/openglui/common/graphics_handler.h"
 
-class EmulatorGraphicsHandler : public GLGraphicsHandler {
+class EmulatorGraphicsHandler : public GraphicsHandler {
   public:
     EmulatorGraphicsHandler(int argc, char** argv);
 
diff --git a/runtime/embedders/openglui/openglui_embedder.gypi b/runtime/embedders/openglui/openglui_embedder.gypi
index 6057f6e..01bf521 100644
--- a/runtime/embedders/openglui/openglui_embedder.gypi
+++ b/runtime/embedders/openglui/openglui_embedder.gypi
@@ -12,6 +12,7 @@
             'target_name': 'android_embedder',
             'type': 'shared_library',
             'dependencies': [
+              'skia-android',
               'libdart_lib_withcore',
               'libdart_vm',
               'libjscre',
@@ -21,10 +22,17 @@
             'include_dirs': [
               '../..',
               '../../../third_party/android_tools/ndk/sources/android/native_app_glue',
+              '../../../third_party/skia/trunk/include',
+              '../../../third_party/skia/trunk/include/config',
+              '../../../third_party/skia/trunk/include/core',
+              '../../../third_party/skia/trunk/include/gpu',
+              '../../../third_party/skia/trunk/include/utils',
             ],
             'defines': [
               'DART_SHARED_LIB',
-              '__ANDROID__'
+              '__ANDROID__',
+              'SK_BUILD_FOR_ANDROID',
+              'SK_BUILD_FOR_ANDROID_NDK',
             ],
             'sources': [
               '../../include/dart_api.h',
@@ -45,14 +53,17 @@
               'android/log.h',
               'android/main.cc',
               'android/support_android.cc',
+              'common/canvas_context.cc',
+              'common/canvas_context.h',
+              'common/canvas_state.cc',
+              'common/canvas_state.h',
               'common/context.h',
               'common/dart_host.cc',
               'common/dart_host.h',
               'common/events.h',
               'common/extension.cc',
               'common/extension.h',
-              'common/gl_graphics_handler.cc',
-              'common/gl_graphics_handler.h',
+              'common/graphics_handler.cc',
               'common/graphics_handler.h',
               'common/input_handler.cc',
               'common/input_handler.h',
@@ -64,6 +75,7 @@
               'common/sample.h',
               'common/sound_handler.cc',
               'common/sound_handler.h',
+              'common/support.h',
               'common/timer.cc',
               'common/timer.h',
               'common/types.h',
@@ -72,15 +84,74 @@
               '<(version_cc_file)',
             ],
             'link_settings': {
-              'libraries': [ '-llog', '-lc', '-landroid', '-lEGL', '-lGLESv2', '-lOpenSLES', '-landroid' ],
               'ldflags': [
-                '-z', 'muldefs'
+                # The libraries we need should all be in
+                # Lthird_party/skia/trunk/out/config/android-x86/Debug but
+                # As I (gram) want to avoid patching the Skia gyp files to build
+                # real libraries we'll just point to the location of the 'thin'
+                # libraries used by the Skia build for now.
+                # TODO(gram): We need to support debug vs release modes.
+                '-Lthird_party/skia/trunk/out/config/android-x86/Debug/obj.target/gyp', 
+                '-z',
+                'muldefs',
+                '-g'
               ],
               'ldflags!': [
-                '-Wl,--exclude-libs=ALL',
+                '-Wl,--exclude-libs=ALL,-shared',
+              ],
+              'libraries': [
+                '-Wl,--start-group',
+                '-lexpat',
+                '-lfreetype',
+                '-lgif',
+                '-ljpeg',
+                '-lpng',
+                '-lskia_core',
+                '-lskia_effects',
+                '-lskia_gr',
+                '-lskia_images',
+                '-lskia_opts',
+                '-lskia_pdf',
+                '-lskia_ports',
+                '-lskia_sfnt',
+                '-lskia_skgr',
+                '-lskia_utils',
+                '-lskia_views',
+                '-lskia_xml',
+                '-lzlib',
+                '-Wl,--end-group',
+                '-llog',
+                '-lc',
+                '-lz',
+                '-landroid',
+                '-lEGL',
+                '-lGLESv2',
+                '-lOpenSLES',
+                '-landroid',
               ],
             },
           },
+          {
+            'target_name': 'skia-android',
+            'type': 'none',
+            'actions': [
+              {
+                'action_name': 'build_skia',
+                'inputs': [
+                  'build_skia.sh'
+                ],
+                'outputs': [
+                  '../../../third_party/skia/trunk/out/config/android-x86/Debug/libskia_core.a'
+                ],
+                'action': [
+                  'embedders/openglui/build_skia.sh',
+                  '--android',
+                  '..'
+                ],
+                'message': 'Building Skia.'
+              }
+            ]
+          }
         ],
       },
     ],
@@ -91,6 +162,7 @@
             'target_name': 'emulator_embedder',
             'type': 'shared_library',
             'dependencies': [
+              'skia-desktop',
               'libdart_lib_withcore',
               'libdart_vm',
               'libjscre',
@@ -99,6 +171,12 @@
             ],
             'include_dirs': [
               '../..',
+              '/usr/X11/include',
+              '../../../third_party/skia/trunk/include',
+              '../../../third_party/skia/trunk/include/config',
+              '../../../third_party/skia/trunk/include/core',
+              '../../../third_party/skia/trunk/include/gpu',
+              '../../../third_party/skia/trunk/include/utils',
             ],
             'defines': [
               'DART_SHARED_LIB'
@@ -109,14 +187,17 @@
               '../../vm/dart_api_impl.cc',
               '../../vm/debugger_api_impl.cc',
               '../../vm/version.h',
+              'common/canvas_context.cc',
+              'common/canvas_context.h',
+              'common/canvas_state.cc',
+              'common/canvas_state.h',
               'common/context.h',
               'common/dart_host.cc',
               'common/dart_host.h',
               'common/events.h',
               'common/extension.cc',
               'common/extension.h',
-              'common/gl_graphics_handler.cc',
-              'common/gl_graphics_handler.h',
+              'common/graphics_handler.cc',
               'common/graphics_handler.h',
               'common/input_handler.cc',
               'common/input_handler.h',
@@ -128,6 +209,8 @@
               'common/sample.h',
               'common/sound_handler.cc',
               'common/sound_handler.h',
+              'common/support.h',
+              'common/support.h',
               'common/timer.cc',
               'common/timer.h',
               'common/types.h',
@@ -140,6 +223,32 @@
               'emulator/emulator_resource.h',
               '<(version_cc_file)',
             ],
+            'link_settings': {
+              'ldflags': [
+                '-Wall',
+                '-g',
+                '-Lthird_party/skia/trunk/out/Debug', 
+                '-Wl,--start-group',
+                '-lskia_effects',
+                '-lskia_images',
+                '-lskia_core',
+                '-lskia_opts',
+                '-lskia_opts_ssse3',
+                '-lskia_ports',
+                '-lskia_sfnt',
+                '-lskia_utils',
+                '-lskia_gr',
+                '-lskia_skgr',
+                '-Wl,--end-group',
+                '-lfreetype',
+              ],
+              'libraries': [
+                '-lGL',
+                '-lglut',
+                '-lGLU',
+                '-lm'
+              ],
+            },
             'conditions': [
               ['OS=="mac"', {
                 'xcode_settings' : {
@@ -148,6 +257,26 @@
               }],
             ]
           },
+          {
+            'target_name': 'skia-desktop',
+            'type': 'none',
+            'actions': [
+              {
+                'action_name': 'build_skia',
+                'inputs': [
+                  'build_skia.sh'
+                ],
+                'outputs': [
+                  '../../../third_party/skia/trunk/out/Debug/libskia_core.a'
+                ],
+                'action': [
+                  'embedders/openglui/build_skia.sh',
+                  '..'
+                ],
+                'message': 'Building Skia.'
+              }
+            ]
+          }
         ],
       },
     ],
diff --git a/runtime/lib/array.dart b/runtime/lib/array.dart
index f72191d..3b457fa 100644
--- a/runtime/lib/array.dart
+++ b/runtime/lib/array.dart
@@ -101,7 +101,7 @@
   }
 
   Iterable map(f(E element)) {
-    return IterableMixinWorkaround.map(this, f);
+    return IterableMixinWorkaround.mapList(this, f);
   }
 
   List mappedBy(f(E element)) {
@@ -331,7 +331,7 @@
   }
 
   Iterable map(f(E element)) {
-    return IterableMixinWorkaround.map(this, f);
+    return IterableMixinWorkaround.mapList(this, f);
   }
 
   List mappedBy(f(E element)) {
diff --git a/runtime/lib/byte_array.dart b/runtime/lib/byte_array.dart
index 74e2c3a..906259c 100644
--- a/runtime/lib/byte_array.dart
+++ b/runtime/lib/byte_array.dart
@@ -230,7 +230,7 @@
   }
 
   Iterable map(f(int element)) {
-    return IterableMixinWorkaround.map(this, f);
+    return IterableMixinWorkaround.mapList(this, f);
   }
 
   List mappedBy(f(int element)) {
diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart
index cd31864..137a583 100644
--- a/runtime/lib/growable_array.dart
+++ b/runtime/lib/growable_array.dart
@@ -38,7 +38,7 @@
     IterableMixinWorkaround.retainAll(this, elements);
   }
 
-  void removeMatching(bool test(E element)) {
+  void removeMatching(bool test(T element)) {
     IterableMixinWorkaround.removeMatchingList(this, test);
   }
 
@@ -243,7 +243,7 @@
   }
 
   Iterable map(f(T element)) {
-    return IterableMixinWorkaround.map(this, f);
+    return IterableMixinWorkaround.mapList(this, f);
   }
 
   List mappedBy(f(T element)) {
diff --git a/runtime/lib/string_base.dart b/runtime/lib/string_base.dart
index 1f6d9fe..c4c62d8 100644
--- a/runtime/lib/string_base.dart
+++ b/runtime/lib/string_base.dart
@@ -40,6 +40,10 @@
 
   int charCodeAt(int index) native "String_charCodeAt";
 
+  int codeUnitAt(int index) {
+    return charCodeAt(index);
+  }
+
   int get length native "String_getLength";
 
   bool get isEmpty {
@@ -429,6 +433,14 @@
     return result;
   }
 
+  Iterable<int> get codeUnits {
+    throw new UnimplementedError("String.codeUnits");
+  }
+
+  Iterable<int> get runes {
+    throw new UnimplementedError("String.runes");
+  }
+
   String toUpperCase() native "String_toUpperCase";
 
   String toLowerCase() native "String_toLowerCase";
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index f1f9301..d6e85f3 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -98,7 +98,8 @@
     ASSERT(!cls.is_finalized());
     super_type ^= cls.super_type();
     if (!super_type.IsNull()) {
-      if (super_type.HasResolvedTypeClass() &&
+      if (!super_type.IsMalformed() &&
+          super_type.HasResolvedTypeClass() &&
           Class::Handle(super_type.type_class()).is_finalized()) {
         AddSuperType(super_type, finalized_super_classes);
       }
@@ -476,7 +477,7 @@
     // Replace unresolved class with resolved type class.
     const Type& parameterized_type = Type::Cast(type);
     if (!type_class.IsNull()) {
-      parameterized_type.set_type_class(Object::Handle(type_class.raw()));
+      parameterized_type.set_type_class(type_class);
     } else {
       // The type class could not be resolved. The type is malformed.
       FinalizeMalformedType(Error::Handle(),  // No previous error.
@@ -735,6 +736,14 @@
         ASSERT(type_arg.IsFinalized());  // Index of type parameter is adjusted.
         full_arguments.SetTypeAt(offset + i, type_arg);
       }
+      // If the type class is a signature class, the full argument vector
+      // must include the argument vector of the super type.
+      // If the signature class is a function type alias, it is also the owner
+      // of its signature function and no super type is involved.
+      // If the signature class is canonical (not an alias), the owner of its
+      // signature function may either be an alias or the enclosing class of a
+      // local function, in which case the super type of the enclosing class is
+      // also considered when filling up the argument vector.
       if (type_class.IsSignatureClass()) {
         const Function& signature_fun =
             Function::Handle(type_class.signature_function());
@@ -802,24 +811,9 @@
   // We do this after marking this type as finalized in order to allow a
   // function type to refer to itself via its parameter types and result type.
   if (type_class.IsSignatureClass()) {
-    // Signature classes are finalized upon creation, except function type
-    // aliases.
-    if (type_class.IsCanonicalSignatureClass()) {
-      ASSERT(type_class.is_finalized());
-      // Resolve and finalize the result and parameter types of the signature
-      // function of this signature class.
-      ASSERT(type_class.SignatureType() == type.raw());
-      ResolveAndFinalizeSignature(
-          type_class, Function::Handle(type_class.signature_function()));
-    } else {
-      // This type is a function type alias. Its class may need to be finalized
-      // and checked for illegal self reference.
-      FinalizeClass(type_class);
-      // Finalizing the signature function here (as in the canonical case above)
-      // would not mark the canonical signature type as finalized.
-      const Type& signature_type = Type::Handle(type_class.SignatureType());
-      FinalizeType(cls, signature_type, finalization);
-    }
+    // The class may be created while parsing a function body, after all
+    // pending classes have already been finalized.
+    FinalizeClass(type_class);
   }
 
   if (finalization >= kCanonicalize) {
@@ -1015,6 +1009,7 @@
   super_class = cls.SuperClass();
   while (!super_class.IsNull()) {
     interfaces.Add(super_class);
+    CollectInterfaces(super_class, interfaces);
     super_class = super_class.SuperClass();
   }
   // Resolve function signatures and check for conflicts in super classes and
@@ -1130,10 +1125,7 @@
     super_type ^= FinalizeType(cls, super_type, kCanonicalizeWellFormed);
     cls.set_super_type(super_type);
   }
-  // Signature classes are finalized upon creation, except function type
-  // aliases.
   if (cls.IsSignatureClass()) {
-    ASSERT(!cls.IsCanonicalSignatureClass());
     // Check for illegal self references.
     GrowableArray<intptr_t> visited_aliases;
     if (!IsAliasCycleFree(cls, &visited_aliases)) {
@@ -1147,6 +1139,15 @@
     // Signature classes extend Object. No need to add this class to the direct
     // subclasses of Object.
     ASSERT(super_type.IsNull() || super_type.IsObjectType());
+
+    // Resolve and finalize the result and parameter types of the signature
+    // function of this signature class.
+    const Function& sig_function = Function::Handle(cls.signature_function());
+    ResolveAndFinalizeSignature(cls, sig_function);
+
+    // Resolve and finalize the signature type of this signature class.
+    const Type& sig_type = Type::Handle(cls.SignatureType());
+    FinalizeType(cls, sig_type, kCanonicalizeWellFormed);
     return;
   }
   // Finalize interface types (but not necessarily interface classes).
@@ -1201,7 +1202,6 @@
 bool ClassFinalizer::IsAliasCycleFree(const Class& cls,
                                       GrowableArray<intptr_t>* visited) {
   ASSERT(cls.IsSignatureClass());
-  ASSERT(!cls.IsCanonicalSignatureClass());
   ASSERT(!cls.is_finalized());
   ASSERT(visited != NULL);
   const intptr_t cls_index = cls.id();
@@ -1222,10 +1222,8 @@
     const Class& type_class = Class::Handle(type.type_class());
     if (!type_class.is_finalized() &&
         type_class.IsSignatureClass() &&
-        !type_class.IsCanonicalSignatureClass()) {
-      if (!IsAliasCycleFree(type_class, visited)) {
-        return false;
-      }
+        !IsAliasCycleFree(type_class, visited)) {
+      return false;
     }
   }
   // Check classes of formal parameter types.
@@ -1237,10 +1235,8 @@
       const Class& type_class = Class::Handle(type.type_class());
       if (!type_class.is_finalized() &&
           type_class.IsSignatureClass() &&
-          !type_class.IsCanonicalSignatureClass()) {
-        if (!IsAliasCycleFree(type_class, visited)) {
-          return false;
-        }
+          !IsAliasCycleFree(type_class, visited)) {
+        return false;
       }
     }
   }
@@ -1511,12 +1507,16 @@
     // In production mode, mark the type as malformed only if its type class is
     // not resolved.
     type.set_malformed_error(error);
+    if (!type.HasResolvedTypeClass()) {
+      // We do not want an unresolved class to end up in a snapshot.
+      type.set_type_class(Object::Handle(Object::null_class()));
+    }
   } else {
      // In production mode, do not mark the type with a resolved type class as
      // malformed, but make it raw.
-    ASSERT(type.HasResolvedTypeClass());
     type.set_arguments(AbstractTypeArguments::Handle());
   }
+  ASSERT(type.HasResolvedTypeClass());
   if (!type.IsFinalized()) {
     type.set_is_finalized_instantiated();
     // Do not canonicalize malformed types, since they may not be resolved.
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index ed4fd7b..e293c89 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -79,29 +79,6 @@
   } while (0)
 
 
-// Return error if isolate is in an inconsistent state.
-// Return NULL when no error condition exists.
-//
-// TODO(turnidge): Make this function return an error handle directly
-// rather than returning an error string.  The current behavior can
-// cause compilation errors to appear to be api errors.
-const char* CheckIsolateState(Isolate* isolate) {
-  if (ClassFinalizer::FinalizePendingClasses() &&
-      isolate->object_store()->PreallocateObjects()) {
-    // Success.
-    return NULL;
-  }
-  // Make a copy of the error message as the original message string
-  // may get deallocated when we return back from the Dart API call.
-  const Error& err = Error::Handle(isolate->object_store()->sticky_error());
-  const char* errmsg = err.ToErrorCString();
-  intptr_t errlen = strlen(errmsg) + 1;
-  char* msg = Api::TopScope(isolate)->zone()->Alloc<char>(errlen);
-  OS::SNPrint(msg, errlen, "%s", errmsg);
-  return msg;
-}
-
-
 void SetupErrorResult(Isolate* isolate, Dart_Handle* handle) {
   *handle = Api::NewHandle(
       isolate, Isolate::Current()->object_store()->sticky_error());
@@ -176,6 +153,17 @@
 }
 
 
+Dart_Handle Api::CheckIsolateState(Isolate* isolate) {
+  if (ClassFinalizer::FinalizePendingClasses() &&
+      isolate->object_store()->PreallocateObjects()) {
+    return Api::Success(isolate);
+  }
+  const Object& obj = Object::Handle(isolate->object_store()->sticky_error());
+  ASSERT(obj.IsError());
+  return Api::NewHandle(isolate, obj.raw());
+}
+
+
 Dart_Isolate Api::CastIsolate(Isolate* isolate) {
   return reinterpret_cast<Dart_Isolate>(isolate);
 }
@@ -905,9 +893,9 @@
   if (size == NULL) {
     RETURN_NULL_ERROR(size);
   }
-  const char* msg = CheckIsolateState(isolate);
-  if (msg != NULL) {
-    return Api::NewError("%s", msg);
+  Dart_Handle state = Api::CheckIsolateState(isolate);
+  if (::Dart_IsError(state)) {
+    return state;
   }
   // Since this is only a snapshot the root library should not be set.
   isolate->object_store()->set_root_library(Library::Handle(isolate));
@@ -929,9 +917,9 @@
   if (size == NULL) {
     RETURN_NULL_ERROR(size);
   }
-  const char* msg = CheckIsolateState(isolate);
-  if (msg != NULL) {
-    return Api::NewError("%s", msg);
+  Dart_Handle state = Api::CheckIsolateState(isolate);
+  if (::Dart_IsError(state)) {
+    return state;
   }
   Library& library =
       Library::Handle(isolate, isolate->object_store()->root_library());
@@ -1255,9 +1243,9 @@
         CURRENT_FUNC);
   }
   // Finalize all classes.
-  const char* msg = CheckIsolateState(isolate);
-  if (msg != NULL) {
-    return Api::NewError("%s", msg);
+  Dart_Handle state = Api::CheckIsolateState(isolate);
+  if (::Dart_IsError(state)) {
+    return state;
   }
   if (obj.IsInstance()) {
     CHECK_CALLBACK_STATE(isolate);
@@ -2530,9 +2518,9 @@
   }
 
   // Finalize all classes.
-  const char* msg = CheckIsolateState(isolate);
-  if (msg != NULL) {
-    return Api::NewError("%s", msg);
+  Dart_Handle state = Api::CheckIsolateState(isolate);
+  if (::Dart_IsError(state)) {
+    return state;
   }
 
   const Array& interface_types = Array::Handle(isolate, cls.interfaces());
@@ -3296,9 +3284,9 @@
   } else {
     RETURN_TYPE_ERROR(isolate, constructor_name, String);
   }
-  const char* msg = CheckIsolateState(isolate);
-  if (msg != NULL) {
-    return Api::NewError("%s", msg);
+  Dart_Handle state = Api::CheckIsolateState(isolate);
+  if (::Dart_IsError(state)) {
+    return state;
   }
 
   // Resolve the constructor.
@@ -3426,9 +3414,9 @@
 
   } else if (obj.IsClass()) {
     // Finalize all classes.
-    const char* msg = CheckIsolateState(isolate);
-    if (msg != NULL) {
-      return Api::NewError("%s", msg);
+    Dart_Handle state = Api::CheckIsolateState(isolate);
+    if (::Dart_IsError(state)) {
+      return state;
     }
 
     const Class& cls = Class::Cast(obj);
@@ -3463,9 +3451,9 @@
 
     // Finalize all classes if needed.
     if (finalize_classes) {
-      const char* msg = CheckIsolateState(isolate);
-      if (msg != NULL) {
-        return Api::NewError("%s", msg);
+      Dart_Handle state = Api::CheckIsolateState(isolate);
+      if (::Dart_IsError(state)) {
+        return state;
       }
     }
 
@@ -3555,9 +3543,9 @@
 
   } else if (obj.IsClass()) {
     // Finalize all classes.
-    const char* msg = CheckIsolateState(isolate);
-    if (msg != NULL) {
-      return Api::NewError("%s", msg);
+    Dart_Handle state = Api::CheckIsolateState(isolate);
+    if (::Dart_IsError(state)) {
+      return state;
     }
     // To access a static field we may need to use the Field or the
     // getter Function.
@@ -4140,10 +4128,9 @@
 DART_EXPORT Dart_Handle Dart_CompileAll() {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
-  Dart_Handle result;
-  const char* msg = CheckIsolateState(isolate);
-  if (msg != NULL) {
-    return Api::NewError("%s", msg);
+  Dart_Handle result = Api::CheckIsolateState(isolate);
+  if (::Dart_IsError(result)) {
+    return result;
   }
   CHECK_CALLBACK_STATE(isolate);
   CompileAll(isolate, &result);
@@ -4293,9 +4280,9 @@
   // If this is the dart:builtin library, register it with the VM.
   if (url_str.Equals("dart:builtin")) {
     isolate->object_store()->set_builtin_library(library);
-    const char* msg = CheckIsolateState(isolate);
-    if (msg != NULL) {
-      return Api::NewError("%s", msg);
+    Dart_Handle state = Api::CheckIsolateState(isolate);
+    if (::Dart_IsError(state)) {
+      return state;
     }
   }
   return result;
diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h
index 2b574f6..32f36bc 100644
--- a/runtime/vm/dart_api_impl.h
+++ b/runtime/vm/dart_api_impl.h
@@ -58,8 +58,6 @@
   HANDLESCOPE(__temp_isolate__);
 
 
-const char* CheckIsolateState(Isolate *isolate);
-
 void SetupErrorResult(Dart_Handle* handle);
 
 
@@ -98,6 +96,10 @@
       const ApiState& state,
       Dart_Handle object);
 
+  // Returns an Error handle if isolate is in an inconsistent state.
+  // Returns a Success handle when no error condition exists.
+  static Dart_Handle CheckIsolateState(Isolate *isolate);
+
   // Casts the internal Isolate* type to the external Dart_Isolate type.
   static Dart_Isolate CastIsolate(Isolate* isolate);
 
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index 301b524..4a10822 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -265,9 +265,9 @@
   }
   intptr_t line = line_number.AsInt64Value();
 
-  const char* msg = CheckIsolateState(isolate);
-  if (msg != NULL) {
-    return Api::NewError("%s", msg);
+  Dart_Handle state = Api::CheckIsolateState(isolate);
+  if (::Dart_IsError(state)) {
+    return state;
   }
 
   Dart_Handle result = Api::True(isolate);
@@ -328,9 +328,9 @@
   UNWRAP_AND_CHECK_PARAM(String, function_name, function_name_in);
   CHECK_NOT_NULL(breakpoint);
 
-  const char* msg = CheckIsolateState(isolate);
-  if (msg != NULL) {
-    return Api::NewError("%s", msg);
+  Dart_Handle state = Api::CheckIsolateState(isolate);
+  if (::Dart_IsError(state)) {
+    return state;
   }
 
   // Resolve the breakpoint target function.
@@ -371,9 +371,9 @@
   UNWRAP_AND_CHECK_PARAM(String, class_name, class_name_in);
   UNWRAP_AND_CHECK_PARAM(String, function_name, function_name_in);
 
-  const char* msg = CheckIsolateState(isolate);
-  if (msg != NULL) {
-    return Api::NewError("%s", msg);
+  Dart_Handle state = Api::CheckIsolateState(isolate);
+  if (::Dart_IsError(state)) {
+    return state;
   }
 
   // Resolve the breakpoint target function.
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index 2ea9813..58ae9ac 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -233,7 +233,7 @@
         (0 == MembershipCount(use, use->definition()->input_use_list())));
     use->set_instruction(instr);
     use->set_use_index(i);
-    use->AddToInputUseList();
+    use->definition()->AddInputUse(use);
   }
 }
 
@@ -252,7 +252,7 @@
         (0 == MembershipCount(use, use->definition()->env_use_list())));
     use->set_instruction(instr);
     use->set_use_index(use_index++);
-    use->AddToEnvUseList();
+    use->definition()->AddEnvUse(use);
   }
 }
 
@@ -297,7 +297,7 @@
             (0 == MembershipCount(use, use->definition()->input_use_list())));
         use->set_instruction(phi);
         use->set_use_index(pred_index);
-        use->AddToInputUseList();
+        use->definition()->AddInputUse(use);
       }
     }
   }
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 3a2d5df..3ce5318 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -224,46 +224,47 @@
 
 void FlowGraphOptimizer::InsertConversion(Representation from,
                                           Representation to,
-                                          Instruction* instr,
                                           Value* use,
-                                          Definition* def,
+                                          Instruction* insert_before,
                                           Instruction* deopt_target) {
   Definition* converted = NULL;
   if ((from == kTagged) && (to == kUnboxedMint)) {
+    ASSERT((deopt_target != NULL) ||
+           (use->definition()->GetPropagatedCid() == kDoubleCid));
     const intptr_t deopt_id = (deopt_target != NULL) ?
         deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
-    ASSERT((deopt_target != NULL) || (def->GetPropagatedCid() == kDoubleCid));
-    converted = new UnboxIntegerInstr(new Value(def), deopt_id);
+    converted = new UnboxIntegerInstr(new Value(use->definition()), deopt_id);
   } else if ((from == kUnboxedMint) && (to == kTagged)) {
-    converted = new BoxIntegerInstr(new Value(def));
+    converted = new BoxIntegerInstr(new Value(use->definition()));
   } else if (from == kUnboxedMint && to == kUnboxedDouble) {
     // Convert by boxing/unboxing.
     // TODO(fschneider): Implement direct unboxed mint-to-double conversion.
-    BoxIntegerInstr* boxed = new BoxIntegerInstr(new Value(def));
-    InsertBefore(instr, boxed, NULL, Definition::kValue);
+    BoxIntegerInstr* boxed = new BoxIntegerInstr(new Value(use->definition()));
+    InsertBefore(insert_before, boxed, NULL, Definition::kValue);
     const intptr_t deopt_id = (deopt_target != NULL) ?
         deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
     converted = new UnboxDoubleInstr(new Value(boxed), deopt_id);
   } else if ((from == kUnboxedDouble) && (to == kTagged)) {
-    converted = new BoxDoubleInstr(new Value(def), NULL);
+    converted = new BoxDoubleInstr(new Value(use->definition()), NULL);
   } else if ((from == kTagged) && (to == kUnboxedDouble)) {
     const intptr_t deopt_id = (deopt_target != NULL) ?
         deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
-    ASSERT((deopt_target != NULL) || (def->GetPropagatedCid() == kDoubleCid));
-    if (def->IsConstant() && def->AsConstant()->value().IsSmi()) {
-      const double dbl_val =
-          Smi::Cast(def->AsConstant()->value()).AsDoubleValue();
+    ASSERT((deopt_target != NULL) ||
+           (use->definition()->GetPropagatedCid() == kDoubleCid));
+    ConstantInstr* constant = use->definition()->AsConstant();
+    if ((constant != NULL) && constant->value().IsSmi()) {
+      const double dbl_val = Smi::Cast(constant->value()).AsDoubleValue();
       const Double& dbl_obj =
           Double::ZoneHandle(Double::New(dbl_val, Heap::kOld));
       ConstantInstr* double_const = new ConstantInstr(dbl_obj);
-      InsertBefore(instr, double_const, NULL, Definition::kValue);
+      InsertBefore(insert_before, double_const, NULL, Definition::kValue);
       converted = new UnboxDoubleInstr(new Value(double_const), deopt_id);
     } else {
-      converted = new UnboxDoubleInstr(new Value(def), deopt_id);
+      converted = new UnboxDoubleInstr(new Value(use->definition()), deopt_id);
     }
   }
   ASSERT(converted != NULL);
-  InsertBefore(instr, converted, use->instruction()->env(),
+  InsertBefore(insert_before, converted, use->instruction()->env(),
                Definition::kValue);
   use->set_definition(converted);
 }
@@ -272,29 +273,31 @@
 void FlowGraphOptimizer::InsertConversionsFor(Definition* def) {
   const Representation from_rep = def->representation();
 
-  for (Value* use = def->input_use_list();
-       use != NULL;
-       use = use->next_use()) {
+  for (Value::Iterator it(def->input_use_list());
+       !it.Done();
+       it.Advance()) {
+    Value* use = it.Current();
     const Representation to_rep =
         use->instruction()->RequiredInputRepresentation(use->use_index());
     if (from_rep == to_rep) {
       continue;
     }
 
-    Instruction* deopt_target = NULL;
-    Instruction* instr = use->instruction();
-    if (instr->IsPhi()) {
-      if (!instr->AsPhi()->is_alive()) continue;
+    Instruction* insert_before;
+    Instruction* deopt_target;
+    PhiInstr* phi = use->instruction()->AsPhi();
+    if (phi != NULL) {
+      if (!phi->is_alive()) continue;
 
       // For phis conversions have to be inserted in the predecessor.
-      const BlockEntryInstr* pred =
-          instr->AsPhi()->block()->PredecessorAt(use->use_index());
-      instr = pred->last_instruction();
+      insert_before =
+          phi->block()->PredecessorAt(use->use_index())->last_instruction();
+      deopt_target = NULL;
     } else {
-      deopt_target = instr;
+      deopt_target = insert_before = use->instruction();
     }
 
-    InsertConversion(from_rep, to_rep, instr, use, def, deopt_target);
+    InsertConversion(from_rep, to_rep, use, insert_before, deopt_target);
   }
 }
 
@@ -522,7 +525,7 @@
 }
 
 
-// Returns array classid to load from, array and idnex value
+// Returns array classid to load from, array and index value
 
 intptr_t FlowGraphOptimizer::PrepareIndexedOp(InstanceCallInstr* call,
                                               intptr_t class_id,
@@ -2199,20 +2202,19 @@
 void RangeAnalysis::RenameDominatedUses(Definition* def,
                                         Instruction* dom,
                                         Definition* other) {
-  Value* next_use = NULL;
-  for (Value* use = def->input_use_list();
-       use != NULL;
-       use = next_use) {
-    next_use = use->next_use();
+  for (Value::Iterator it(def->input_use_list());
+       !it.Done();
+       it.Advance()) {
+    Value* use = it.Current();
 
     // Skip dead phis.
     PhiInstr* phi = use->instruction()->AsPhi();
     if ((phi != NULL) && !phi->is_alive()) continue;
 
     if (IsDominatedUse(dom, use)) {
-      use->RemoveFromInputUseList();
+      use->RemoveFromUseList();
       use->set_definition(other);
-      use->AddToInputUseList();
+      other->AddInputUse(use);
     }
   }
 }
@@ -2288,15 +2290,15 @@
   // No need to constrain constants.
   if (defn->IsConstant()) return NULL;
 
-  ConstraintInstr* constraint =
-      new ConstraintInstr(new Value(defn), constraint_range);
+  Value* value = new Value(defn);
+  ConstraintInstr* constraint = new ConstraintInstr(value, constraint_range);
   constraint->InsertAfter(after);
   constraint->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
   RenameDominatedUses(defn, after, constraint);
   constraints_.Add(constraint);
-  constraint->value()->set_instruction(constraint);
-  constraint->value()->set_use_index(0);
-  constraint->value()->AddToInputUseList();
+  value->set_instruction(constraint);
+  value->set_use_index(0);
+  defn->AddInputUse(value);
   return constraint;
 }
 
@@ -2906,7 +2908,7 @@
                                       BlockEntryInstr* header,
                                       BlockEntryInstr* pre_header,
                                       CheckSmiInstr* current) {
-  PhiInstr* phi = current->InputAt(0)->definition()->AsPhi();
+  PhiInstr* phi = current->value()->definition()->AsPhi();
   if (!header->loop_info()->Contains(phi->block()->preorder_number())) {
     return;
   }
@@ -2943,9 +2945,9 @@
 
   // Replace value we are checking with phi's input. Maintain use lists.
   Definition* non_smi_input_defn = phi->InputAt(non_smi_input)->definition();
-  current->value()->RemoveFromInputUseList();
+  current->value()->RemoveFromUseList();
   current->value()->set_definition(non_smi_input_defn);
-  current->value()->AddToInputUseList();
+  non_smi_input_defn->AddInputUse(current->value());
 
   phi->SetPropagatedCid(kSmiCid);
 }
@@ -3478,13 +3480,14 @@
       // from the graph by this iteration.
       // To prevent using them we additionally mark definitions themselves
       // as replaced and store a pointer to the replacement.
-      Value* input = new Value((*pred_out_values)[expr_id]->Replacement());
+      Definition* replacement = (*pred_out_values)[expr_id]->Replacement();
+      Value* input = new Value(replacement);
       phi->SetInputAt(i, input);
 
       // TODO(vegorov): add a helper function to handle input insertion.
       input->set_instruction(phi);
       input->set_use_index(i);
-      input->AddToInputUseList();
+      replacement->AddInputUse(input);
     }
 
     phi->set_ssa_temp_index(graph_->alloc_ssa_temp_index());
diff --git a/runtime/vm/flow_graph_optimizer.h b/runtime/vm/flow_graph_optimizer.h
index 7b4d055..53159fc 100644
--- a/runtime/vm/flow_graph_optimizer.h
+++ b/runtime/vm/flow_graph_optimizer.h
@@ -86,9 +86,8 @@
 
   void InsertConversion(Representation from,
                         Representation to,
-                        Instruction* instr,
                         Value* use,
-                        Definition* def,
+                        Instruction* insert_before,
                         Instruction* deopt_target);
 
   bool InstanceCallNeedsClassCheck(InstanceCallInstr* call) const;
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index d5284b7..11b2713 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -626,58 +626,73 @@
 }
 
 
-void Value::AddToInputUseList() {
-  Value* next = definition()->input_use_list();
-  definition()->set_input_use_list(this);
-  set_next_use(next);
-  set_previous_use(NULL);
-  if (next != NULL) next->set_previous_use(this);
+void Value::AddToList(Value* value, Value** list) {
+  Value* next = *list;
+  *list = value;
+  value->set_next_use(next);
+  value->set_previous_use(NULL);
+  if (next != NULL) next->set_previous_use(value);
 }
 
 
-void Value::AddToEnvUseList() {
-  Value* next = definition()->env_use_list();
-  definition()->set_env_use_list(this);
-  set_next_use(next);
-  set_previous_use(NULL);
-  if (next != NULL) next->set_previous_use(this);
-}
-
-
-void Value::RemoveFromInputUseList() {
-  Value* previous = previous_use();
+void Value::RemoveFromUseList() {
+  Definition* def = definition();
   Value* next = next_use();
-  if (previous == NULL) {
-    definition()->set_input_use_list(next);
+  if (this == def->input_use_list()) {
+    def->set_input_use_list(next);
+    if (next != NULL) next->set_previous_use(NULL);
+  } else if (this == def->env_use_list()) {
+    def->set_env_use_list(next);
+    if (next != NULL) next->set_previous_use(NULL);
   } else {
-    previous->set_next_use(next);
+    Value* prev = previous_use();
+    prev->set_next_use(next);
+    if (next != NULL) next->set_previous_use(prev);
   }
-  if (next != NULL) next->set_previous_use(previous);
+
   set_definition(NULL);
+  set_previous_use(NULL);
+  set_next_use(NULL);
 }
 
 
 void Definition::ReplaceUsesWith(Definition* other) {
   ASSERT(other != NULL);
   ASSERT(this != other);
+
+  Value* current = NULL;
   Value* next = input_use_list();
-  while (next != NULL) {
-    Value* current = next;
-    next = current->next_use();
-    current->set_definition(other);
-    current->AddToInputUseList();
+  if (next != NULL) {
+    // Change all the definitions.
+    while (next != NULL) {
+      current = next;
+      current->set_definition(other);
+      next = current->next_use();
+    }
+
+    // Concatenate the lists.
+    next = other->input_use_list();
+    current->set_next_use(next);
+    if (next != NULL) next->set_previous_use(current);
+    other->set_input_use_list(input_use_list());
+    set_input_use_list(NULL);
   }
 
+  // Repeat for environment uses.
+  current = NULL;
   next = env_use_list();
-  while (next != NULL) {
-    Value* current = next;
-    next = current->next_use();
-    current->set_definition(other);
-    current->AddToEnvUseList();
+  if (next != NULL) {
+    while (next != NULL) {
+      current = next;
+      current->set_definition(other);
+      next = current->next_use();
+    }
+    next = other->env_use_list();
+    current->set_next_use(next);
+    if (next != NULL) next->set_previous_use(current);
+    other->set_env_use_list(env_use_list());
+    set_env_use_list(NULL);
   }
-
-  set_input_use_list(NULL);
-  set_env_use_list(NULL);
 }
 
 
@@ -1362,6 +1377,16 @@
 }
 
 
+bool BinarySmiOpInstr::RightIsPowerOfTwoConstant() const {
+  if (!right()->definition()->IsConstant()) return false;
+  const Object& constant = right()->definition()->AsConstant()->value();
+  if (!constant.IsSmi()) return false;
+  const intptr_t int_value = Smi::Cast(constant).Value();
+  if (int_value == 0) return false;
+  return Utils::IsPowerOfTwo(Utils::Abs(int_value));
+}
+
+
 RawAbstractType* BinaryMintOpInstr::CompileType() const {
   return Type::IntType();
 }
@@ -1770,9 +1795,9 @@
     // It is ok to insert instructions before the current during
     // forward iteration.
     optimizer->InsertBefore(this, null_constant, NULL, Definition::kValue);
-    instantiator_type_arguments()->RemoveFromInputUseList();
+    instantiator_type_arguments()->RemoveFromUseList();
     instantiator_type_arguments()->set_definition(null_constant);
-    instantiator_type_arguments()->AddToInputUseList();
+    null_constant->AddInputUse(instantiator_type_arguments());
   }
   return this;
 }
@@ -2125,7 +2150,7 @@
     Value* value = it.CurrentValue();
     value->set_instruction(instr);
     value->set_use_index(use_index++);
-    value->AddToEnvUseList();
+    value->definition()->AddEnvUse(value);
   }
   instr->set_env(copy);
 }
@@ -2151,7 +2176,7 @@
     Value* value = it.CurrentValue();
     value->set_instruction(instr);
     value->set_use_index(use_index++);
-    value->AddToEnvUseList();
+    value->definition()->AddEnvUse(value);
   }
   instr->env()->outer_ = copy;
 }
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index d2ae0d0..8c3b695 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -71,6 +71,23 @@
 
 class Value : public ZoneAllocated {
  public:
+  // A forward iterator that allows removing the current value from the
+  // underlying use list during iteration.
+  class Iterator {
+   public:
+    explicit Iterator(Value* head) : next_(head) { Advance(); }
+    Value* Current() const { return current_; }
+    bool Done() const { return current_ == NULL; }
+    void Advance() {
+      // Pre-fetch next on advance and cache it.
+      current_ = next_;
+      if (next_ != NULL) next_ = next_->next_use();
+    }
+   private:
+    Value* current_;
+    Value* next_;
+  };
+
   explicit Value(Definition* definition)
       : definition_(definition),
         previous_use_(NULL),
@@ -94,10 +111,8 @@
   intptr_t use_index() const { return use_index_; }
   void set_use_index(intptr_t index) { use_index_ = index; }
 
-  void AddToInputUseList();
-  void AddToEnvUseList();
-
-  void RemoveFromInputUseList();
+  static void AddToList(Value* value, Value** list);
+  void RemoveFromUseList();
 
   Value* Copy() { return new Value(definition_); }
 
@@ -1109,6 +1124,9 @@
   Value* env_use_list() const { return env_use_list_; }
   void set_env_use_list(Value* head) { env_use_list_ = head; }
 
+  void AddInputUse(Value* value) { Value::AddToList(value, &input_use_list_); }
+  void AddEnvUse(Value* value) { Value::AddToList(value, &env_use_list_); }
+
   // Replace uses of this definition with uses of other definition or value.
   // Precondition: use lists must be properly calculated.
   // Postcondition: use lists and use values are still valid.
@@ -1810,13 +1828,13 @@
     Value* val = new Value(defn);
     val->set_use_index(1);
     val->set_instruction(this);
-    val->AddToInputUseList();
+    defn->AddInputUse(val);
     set_dependency(val);
   }
 
   void RemoveDependency() {
     if (dependency() != NULL) {
-      dependency()->RemoveFromInputUseList();
+      dependency()->RemoveFromUseList();
       set_dependency(NULL);
     }
   }
@@ -3881,6 +3899,10 @@
 
   virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer);
 
+  // Returns true if right is a non-zero Smi constant which absolute value is
+  // a power of two.
+  bool RightIsPowerOfTwoConstant() const;
+
  private:
   const Token::Kind op_kind_;
   InstanceCallInstr* instance_call_;
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 62d423d..a698a59 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -1954,12 +1954,20 @@
     const intptr_t kNumTemps = 1;
     LocationSummary* summary =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
-    // Both inputs must be writable because they will be untagged.
-    summary->set_in(0, Location::RegisterLocation(EAX));
-    summary->set_in(1, Location::WritableRegister());
-    summary->set_out(Location::SameAsFirstInput());
-    // Will be used for sign extension and division.
-    summary->set_temp(0, Location::RegisterLocation(EDX));
+    if (RightIsPowerOfTwoConstant()) {
+      summary->set_in(0, Location::RequiresRegister());
+      ConstantInstr* right_constant = right()->definition()->AsConstant();
+      summary->set_in(1, Location::Constant(right_constant->value()));
+      summary->set_temp(0, Location::RequiresRegister());
+      summary->set_out(Location::SameAsFirstInput());
+    } else {
+      // Both inputs must be writable because they will be untagged.
+      summary->set_in(0, Location::RegisterLocation(EAX));
+      summary->set_in(1, Location::WritableRegister());
+      summary->set_out(Location::SameAsFirstInput());
+      // Will be used for sign extension and division.
+      summary->set_temp(0, Location::RegisterLocation(EDX));
+    }
     return summary;
   } else if (op_kind() == Token::kSHR) {
     const intptr_t kNumTemps = 0;
@@ -1996,8 +2004,7 @@
   ASSERT(left == result);
   Label* deopt = NULL;
   if (CanDeoptimize()) {
-      deopt  = compiler->AddDeoptStub(deopt_id(),
-                                      kDeoptBinarySmiOp);
+    deopt  = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
   }
 
   if (locs()->in(1).IsConstant()) {
@@ -2022,6 +2029,37 @@
         if (deopt != NULL) __ j(OVERFLOW, deopt);
         break;
       }
+      case Token::kTRUNCDIV: {
+        const intptr_t value = Smi::Cast(constant).Value();
+        if (value == 1) {
+          // Do nothing.
+          break;
+        } else if (value == -1) {
+          // Check the corner case of dividing the 'MIN_SMI' with -1, in which
+          // case we cannot negate the result.
+          __ cmpl(left, Immediate(0x80000000));
+          __ j(EQUAL, deopt);
+          __ negl(left);
+          break;
+        }
+        ASSERT((value != 0) && Utils::IsPowerOfTwo(Utils::Abs(value)));
+        const intptr_t shift_count =
+            Utils::ShiftForPowerOfTwo(Utils::Abs(value)) + kSmiTagSize;
+        ASSERT(kSmiTagSize == 1);
+        Register temp = locs()->temp(0).reg();
+        __ movl(temp, left);
+        __ sarl(temp, Immediate(31));
+        ASSERT(shift_count > 1);  // 1, -1 case handled above.
+        __ shrl(temp, Immediate(32 - shift_count));
+        __ addl(left, temp);
+        ASSERT(shift_count > 0);
+        __ sarl(left, Immediate(shift_count));
+        if (value < 0) {
+          __ negl(left);
+        }
+        __ SmiTag(left);
+        break;
+      }
       case Token::kBIT_AND: {
         // No overflow check.
         __ andl(left, Immediate(imm));
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 59b9855..b0d714a 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -1786,6 +1786,7 @@
     Immediate(reinterpret_cast<int64_t>(constant.raw())).is_int32();
 }
 
+
 LocationSummary* BinarySmiOpInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 2;
 
@@ -1808,12 +1809,20 @@
     const intptr_t kNumTemps = 1;
     LocationSummary* summary =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
-    // Both inputs must be writable because they will be untagged.
-    summary->set_in(0, Location::RegisterLocation(RAX));
-    summary->set_in(1, Location::WritableRegister());
-    summary->set_out(Location::SameAsFirstInput());
-    // Will be used for sign extension and division.
-    summary->set_temp(0, Location::RegisterLocation(RDX));
+    if (RightIsPowerOfTwoConstant()) {
+      summary->set_in(0, Location::RequiresRegister());
+      ConstantInstr* right_constant = right()->definition()->AsConstant();
+      summary->set_in(1, Location::Constant(right_constant->value()));
+      summary->set_temp(0, Location::RequiresRegister());
+      summary->set_out(Location::SameAsFirstInput());
+    } else {
+      // Both inputs must be writable because they will be untagged.
+      summary->set_in(0, Location::RegisterLocation(RAX));
+      summary->set_in(1, Location::WritableRegister());
+      summary->set_out(Location::SameAsFirstInput());
+      // Will be used for sign extension and division.
+      summary->set_temp(0, Location::RegisterLocation(RDX));
+    }
     return summary;
   } else if (op_kind() == Token::kSHR) {
     const intptr_t kNumTemps = 0;
@@ -1843,7 +1852,6 @@
   }
 }
 
-
 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   Register left = locs()->in(0).reg();
   Register result = locs()->out().reg();
@@ -1877,6 +1885,38 @@
         if (deopt != NULL) __ j(OVERFLOW, deopt);
         break;
       }
+      case Token::kTRUNCDIV: {
+        const intptr_t value = Smi::Cast(constant).Value();
+        if (value == 1) {
+          // Do nothing.
+          break;
+        } else if (value == -1) {
+          // Check the corner case of dividing the 'MIN_SMI' with -1, in which
+          // case we cannot negate the result.
+          __ cmpq(left, Immediate(0x8000000000000000));
+          __ j(EQUAL, deopt);
+          __ negq(left);
+          break;
+        }
+
+        ASSERT((value != 0) && Utils::IsPowerOfTwo(Utils::Abs(value)));
+        const intptr_t shift_count =
+            Utils::ShiftForPowerOfTwo(Utils::Abs(value)) + kSmiTagSize;
+        ASSERT(kSmiTagSize == 1);
+        Register temp = locs()->temp(0).reg();
+        __ movq(temp, left);
+        __ sarq(temp, Immediate(63));
+        ASSERT(shift_count > 1);  // 1, -1 case handled above.
+        __ shrq(temp, Immediate(64 - shift_count));
+        __ addq(left, temp);
+        ASSERT(shift_count > 0);
+        __ sarq(left, Immediate(shift_count));
+        if (value < 0) {
+          __ negq(left);
+        }
+        __ SmiTag(left);
+        break;
+      }
       case Token::kBIT_AND: {
         // No overflow check.
         __ andq(left, Immediate(imm));
diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc
index 3b25aa1..aa78b99 100644
--- a/runtime/vm/intrinsifier.cc
+++ b/runtime/vm/intrinsifier.cc
@@ -6,13 +6,16 @@
 #include "vm/intrinsifier.h"
 #include "vm/flags.h"
 #include "vm/object.h"
+#include "vm/symbols.h"
 
 namespace dart {
 
 DEFINE_FLAG(bool, intrinsify, true, "Instrinsify when possible");
 
 
-static bool CompareNames(const char* test_name, const char* name) {
+static bool CompareNames(const Library& lib,
+                         const char* test_name,
+                         const char* name) {
   static const char* kPrivateGetterPrefix = "get:_";
   static const char* kPrivateSetterPrefix = "set:_";
 
@@ -40,20 +43,11 @@
     return (strcmp(test_name, name) == 0);
   }
 
-  // Check if the private class is member of core or scalarlist and matches
+  // Check if the private class is member of the library and matches
   // the test_class_name.
-  const Library& core_lib = Library::Handle(Library::CoreLibrary());
-  const Library& scalarlist_lib =
-      Library::Handle(Library::ScalarlistLibrary());
-  String& test_str = String::Handle(String::New(test_name));
-  String& test_str_with_key = String::Handle();
-  test_str_with_key =
-      String::Concat(test_str, String::Handle(core_lib.private_key()));
-  if (strcmp(test_str_with_key.ToCString(), name) == 0) {
-    return true;
-  }
-  test_str_with_key =
-      String::Concat(test_str, String::Handle(scalarlist_lib.private_key()));
+  const String& test_str = String::Handle(String::New(test_name));
+  const String& test_str_with_key = String::Handle(
+      String::Concat(test_str, String::Handle(lib.private_key())));
   if (strcmp(test_str_with_key.ToCString(), name) == 0) {
     return true;
   }
@@ -64,7 +58,8 @@
 
 // Returns true if the function matches function_name and class_name, with
 // special recognition of corelib private classes.
-static bool TestFunction(const Function& function,
+static bool TestFunction(const Library& lib,
+                         const Function& function,
                          const char* function_class_name,
                          const char* function_name,
                          const char* test_class_name,
@@ -73,14 +68,17 @@
   // that it is a named constructor in the class. Therefore, if
   // the class matches and the rest of the method name starting with
   // the dot matches, we have found a match.
+  // We do not store the entire factory constructor name with the class
+  // (e.g: _GrowableObjectArray.withData) because the actual function name
+  //  that we see here includes the private key.
   if (test_function_name[0] == '.') {
     function_name = strstr(function_name, ".");
     if (function_name == NULL) {
       return false;
     }
   }
-  return CompareNames(test_class_name, function_class_name) &&
-         CompareNames(test_function_name, function_name);
+  return CompareNames(lib, test_class_name, function_class_name) &&
+         CompareNames(lib, test_function_name, function_name);
 }
 
 
@@ -89,50 +87,76 @@
   if (function.IsClosureFunction()) return false;
   // Can occur because of compile-all flag.
   if (function.is_external()) return false;
-  // Intrinsic kind is set lazily below.
-  if (function.intrinsic_kind() == Function::kIsIntrinsic) return true;
-  if (function.intrinsic_kind() == Function::kIsNotIntrinsic) return false;
-  // Closure functions may have different arguments.
-  const char* function_name = String::Handle(function.name()).ToCString();
-  const Class& function_class = Class::Handle(function.Owner());
-  // Only core, math and scalarlist library methods can be intrinsified.
-  if ((function_class.library() != Library::CoreLibrary()) &&
-      (function_class.library() != Library::MathLibrary()) &&
-      (function_class.library() != Library::ScalarlistLibrary())) {
-    return false;
-  }
-  const char* class_name = String::Handle(function_class.Name()).ToCString();
-#define FIND_INTRINSICS(test_class_name, test_function_name, destination, fp)  \
-  if (TestFunction(function,                                                   \
-                   class_name, function_name,                                  \
-                   #test_class_name, #test_function_name)) {                   \
-    function.set_intrinsic_kind(Function::kIsIntrinsic);                       \
-    return true;                                                               \
-  }                                                                            \
+  return function.is_intrinsic();
+}
 
-INTRINSIC_LIST(FIND_INTRINSICS);
-#undef FIND_INTRINSICS
-  function.set_intrinsic_kind(Function::kIsNotIntrinsic);
-  return false;
+
+void Intrinsifier::InitializeState() {
+  Library& lib = Library::Handle();
+  Class& cls = Class::Handle();
+  Function& func = Function::Handle();
+  String& str = String::Handle();
+
+#define SETUP_FUNCTION(class_name, function_name, destination, fp)             \
+  if (strcmp(#class_name, "::") == 0) {                                        \
+    str = String::New(#function_name);                                         \
+    func = lib.LookupFunctionAllowPrivate(str);                                \
+  } else {                                                                     \
+    str = String::New(#class_name);                                            \
+    cls = lib.LookupClassAllowPrivate(str);                                    \
+    ASSERT(!cls.IsNull());                                                     \
+    if (#function_name[0] == '.') {                                            \
+      str = String::New(#class_name#function_name);                            \
+    } else {                                                                   \
+      str = String::New(#function_name);                                       \
+    }                                                                          \
+    func = cls.LookupFunctionAllowPrivate(str);                                \
+  }                                                                            \
+  ASSERT(!func.IsNull());                                                      \
+  func.set_is_intrinsic(true);                                                 \
+
+  // Set up all core lib functions that can be intrisified.
+  lib = Library::CoreLibrary();
+  CORE_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
+
+  // Set up all math lib functions that can be intrisified.
+  lib = Library::MathLibrary();
+  MATH_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
+
+  // Set up all scalar list lib functions that can be intrisified.
+  lib = Library::ScalarlistLibrary();
+  SCALARLIST_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
+
+#undef SETUP_FUNCTION
 }
 
 
 bool Intrinsifier::Intrinsify(const Function& function, Assembler* assembler) {
   if (!CanIntrinsify(function)) return false;
+
   const char* function_name = String::Handle(function.name()).ToCString();
   const Class& function_class = Class::Handle(function.Owner());
   const char* class_name = String::Handle(function_class.Name()).ToCString();
+  const Library& lib = Library::Handle(function_class.library());
+
 #define FIND_INTRINSICS(test_class_name, test_function_name, destination, fp)  \
-  if (TestFunction(function,                                                   \
+  if (TestFunction(lib, function,                                              \
                    class_name, function_name,                                  \
                    #test_class_name, #test_function_name)) {                   \
     ASSERT(function.CheckSourceFingerprint(fp));                               \
     return destination(assembler);                                             \
   }                                                                            \
 
-INTRINSIC_LIST(FIND_INTRINSICS);
-#undef FIND_INTRINSICS
+  if (lib.raw() == Library::CoreLibrary()) {
+    CORE_LIB_INTRINSIC_LIST(FIND_INTRINSICS);
+  } else if (lib.raw() == Library::ScalarlistLibrary()) {
+    SCALARLIST_LIB_INTRINSIC_LIST(FIND_INTRINSICS);
+  } else if (lib.raw() == Library::MathLibrary()) {
+    MATH_LIB_INTRINSIC_LIST(FIND_INTRINSICS);
+  }
   return false;
+
+#undef FIND_INTRINSICS
 }
 
 }  // namespace dart
diff --git a/runtime/vm/intrinsifier.h b/runtime/vm/intrinsifier.h
index a82f317..3ac1014 100644
--- a/runtime/vm/intrinsifier.h
+++ b/runtime/vm/intrinsifier.h
@@ -15,7 +15,7 @@
 //
 // When adding a new function for intrinsification add a 0 as fingerprint,
 // build and run to get the correct fingerprint from the mismatch error.
-#define INTRINSIC_LIST(V)                                                      \
+#define CORE_LIB_INTRINSIC_LIST(V)                                             \
   V(_IntegerImplementation, _addFromInteger, Integer_addFromInteger, 726019207)\
   V(_IntegerImplementation, +, Integer_add, 959303888)                         \
   V(_IntegerImplementation, _subFromInteger, Integer_subFromInteger, 726019207)\
@@ -74,14 +74,20 @@
   V(_GrowableObjectArray, add, GrowableArray_add, 1367698386)                  \
   V(_ImmutableArray, [], ImmutableArray_getIndexed, 486821199)                 \
   V(_ImmutableArray, get:length, ImmutableArray_getLength, 433698233)          \
-  V(::, sqrt, Math_sqrt, 1662640002)                                           \
-  V(::, sin, Math_sin, 1273932041)                                             \
-  V(::, cos, Math_cos, 1749547468)                                             \
   V(Object, ==, Object_equal, 2126956595)                                      \
   V(_StringBase, get:hashCode, String_getHashCode, 320803993)                  \
   V(_StringBase, get:isEmpty, String_getIsEmpty, 711547329)                    \
   V(_StringBase, get:length, String_getLength, 320803993)                      \
   V(_StringBase, charCodeAt, String_charCodeAt, 984449525)                     \
+
+
+#define MATH_LIB_INTRINSIC_LIST(V)                                             \
+  V(::, sqrt, Math_sqrt, 1662640002)                                           \
+  V(::, sin, Math_sin, 1273932041)                                             \
+  V(::, cos, Math_cos, 1749547468)                                             \
+
+
+#define SCALARLIST_LIB_INTRINSIC_LIST(V)                                       \
   V(_ByteArrayBase, get:length, ByteArrayBase_getLength, 1098081765)           \
   V(_Int8Array, [], Int8Array_getIndexed, 1295306322)                          \
   V(_Int8Array, []=, Int8Array_setIndexed, 1709956322)                         \
@@ -112,6 +118,11 @@
   V(_Float64Array, []=, Float64Array_setIndexed, 1948811847)                   \
   V(_Float64Array, _new, Float64Array_new, 147668392)                          \
   V(_ExternalUint8Array, [], ExternalUint8Array_getIndexed, 753790851)         \
+  V(_ExternalUint8ClampedArray, [], ExternalUint8ClampedArray_getIndexed,      \
+      823759763)                                                               \
+  V(_ExternalUint8ClampedArray, []=, ExternalUint8ClampedArray_setIndexed,     \
+      654373808)                                                               \
+
 
 // TODO(srdjan): Implement _FixedSizeArrayIterator, get:current and
 //   _FixedSizeArrayIterator, moveNext.
@@ -127,12 +138,16 @@
   // path possible).
   static bool Intrinsify(const Function& function, Assembler* assembler);
   static bool CanIntrinsify(const Function& function);
+  static void InitializeState();
 
  private:
 #define DECLARE_FUNCTION(test_class_name, test_function_name, destination, fp) \
   static bool destination(Assembler* assembler);
 
-INTRINSIC_LIST(DECLARE_FUNCTION)
+  CORE_LIB_INTRINSIC_LIST(DECLARE_FUNCTION)
+  MATH_LIB_INTRINSIC_LIST(DECLARE_FUNCTION)
+  SCALARLIST_LIB_INTRINSIC_LIST(DECLARE_FUNCTION)
+
 #undef DECLARE_FUNCTION
 };
 
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index 5de8051..e606969 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -229,6 +229,16 @@
 }
 
 
+bool Intrinsifier::ExternalUint8ClampedArray_getIndexed(Assembler* assembler) {
+  return false;
+}
+
+
+bool Intrinsifier::ExternalUint8ClampedArray_setIndexed(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Integer_addFromInteger(Assembler* assembler) {
   return false;
 }
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index 114a1b2..b939f78 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -987,6 +987,52 @@
 }
 
 
+bool Intrinsifier::ExternalUint8ClampedArray_getIndexed(Assembler* assembler) {
+  Label fall_through;
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // EBX: index as Smi.
+  // EAX: array.
+  __ SmiUntag(EBX);
+  __ movl(EAX, FieldAddress(EAX, ExternalUint8ClampedArray::data_offset()));
+  __ movzxb(EAX, Address(EAX, EBX, TIMES_1, 0));
+  __ SmiTag(EAX);
+  __ ret();
+  __ Bind(&fall_through);
+  return false;
+}
+
+
+bool Intrinsifier::ExternalUint8ClampedArray_setIndexed(Assembler* assembler) {
+  Label fall_through, store_value, load_0xff;
+  TestByteArraySetIndex(assembler, &fall_through);
+  // EBX: index as Smi.
+  // EAX: array.
+  __ SmiUntag(EBX);
+  __ movl(EAX, FieldAddress(EAX, ExternalUint8ClampedArray::data_offset()));
+  // Free EBX for the value since we need a byte register.
+  __ leal(EAX, Address(EAX, EBX, TIMES_1, 0));
+  __ movl(EBX, Address(ESP, + 1 * kWordSize));  // Value.
+  __ testl(EBX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);
+
+  __ SmiUntag(EBX);
+  __ cmpl(EBX, Immediate(0xFF));
+  __ j(BELOW_EQUAL, &store_value, Assembler::kNearJump);
+  // Clamp to 0x00 or 0xFF respectively.
+  __ j(GREATER, &load_0xff,  Assembler::kNearJump);
+  __ xorl(EBX, EBX);  // Zero.
+  __ jmp(&store_value, Assembler::kNearJump);
+  __ Bind(&load_0xff);
+  __ movl(EBX, Immediate(0xFF));
+
+  __ Bind(&store_value);
+  __ movb(Address(EAX, 0), BL);
+  __ ret();
+  __ Bind(&fall_through);
+  return false;
+}
+
+
 // Tests if two top most arguments are smis, jumps to label not_smi if not.
 // Topmost argument is in EAX.
 static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index e71febb..5c07f27 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -229,6 +229,16 @@
 }
 
 
+bool Intrinsifier::ExternalUint8ClampedArray_getIndexed(Assembler* assembler) {
+  return false;
+}
+
+
+bool Intrinsifier::ExternalUint8ClampedArray_setIndexed(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Integer_addFromInteger(Assembler* assembler) {
   return false;
 }
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index cd1d7d2..8d75a2e 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -970,6 +970,49 @@
 }
 
 
+bool Intrinsifier::ExternalUint8ClampedArray_getIndexed(Assembler* assembler) {
+  Label fall_through;
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // R12: index as Smi.
+  // RAX: array.
+  __ SmiUntag(R12);
+  __ movq(RAX, FieldAddress(RAX, ExternalUint8ClampedArray::data_offset()));
+  __ movzxb(RAX, Address(RAX, R12, TIMES_1, 0));
+  __ SmiTag(RAX);
+  __ ret();
+  __ Bind(&fall_through);
+  return false;
+}
+
+
+bool Intrinsifier::ExternalUint8ClampedArray_setIndexed(Assembler* assembler) {
+  Label fall_through, store_value, load_0xff;
+  TestByteArraySetIndex(assembler, &fall_through);
+  // R12: index as Smi.
+  // RAX: array.
+  __ SmiUntag(R12);
+  __ movq(RDI, Address(RSP, + 1 * kWordSize));  // Value.
+  __ testq(RDI, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);
+
+  __ SmiUntag(RDI);
+  __ cmpq(RDI, Immediate(0xFF));
+  __ j(BELOW_EQUAL, &store_value, Assembler::kNearJump);
+  __ j(GREATER, &load_0xff,  Assembler::kNearJump);
+  __ xorq(RDI, RDI);  // Zero.
+  __ jmp(&store_value, Assembler::kNearJump);
+  __ Bind(&load_0xff);
+  __ movq(RDI, Immediate(0xFF));
+
+  __ Bind(&store_value);
+  __ movq(RAX, FieldAddress(RAX, ExternalUint8ClampedArray::data_offset()));
+  __ movb(Address(RAX, R12, TIMES_1, 0), RDI);
+  __ ret();
+  __ Bind(&fall_through);
+  return false;
+}
+
+
 // Tests if two top most arguments are smis, jumps to label not_smi if not.
 // Topmost argument is in RAX.
 static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index ec3cb20..fc20192 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -25,6 +25,7 @@
 #include "vm/exceptions.h"
 #include "vm/growable_array.h"
 #include "vm/heap.h"
+#include "vm/intrinsifier.h"
 #include "vm/object_store.h"
 #include "vm/parser.h"
 #include "vm/runtime_entry.h"
@@ -1090,6 +1091,10 @@
 
   ClassFinalizer::VerifyBootstrapClasses();
   MarkInvisibleFunctions();
+
+  // Set up the intrinsic state of all functions (core, math and scalar list).
+  Intrinsifier::InitializeState();
+
   return Error::null();
 }
 
@@ -1443,7 +1448,9 @@
   ASSERT(!signature_types.IsNull());
   if (signature_types.Length() > 0) {
     // At most one signature type per signature class.
-    ASSERT(signature_types.Length() == 1);
+    ASSERT((signature_types.Length() == 1) ||
+           ((signature_types.Length() == 2) &&
+            (signature_types.At(1) == Type::null())));
     Type& signature_type = Type::Handle();
     signature_type ^= signature_types.At(0);
     ASSERT(!signature_type.IsNull());
@@ -1915,7 +1922,29 @@
 
 RawClass* Class::NewSignatureClass(const String& name,
                                    const Function& signature_function,
-                                   const Script& script) {
+                                   const Script& script,
+                                   intptr_t token_pos) {
+  const Class& result = Class::Handle(New<Instance>(name, script, token_pos));
+  const Type& super_type = Type::Handle(Type::ObjectType());
+  ASSERT(!super_type.IsNull());
+  // Instances of a signature class can only be closures.
+  result.set_instance_size(Closure::InstanceSize());
+  result.set_next_field_offset(Closure::InstanceSize());
+  result.set_super_type(super_type);
+  result.set_type_arguments_field_offset(Closure::type_arguments_offset());
+  // Implements interface "Function".
+  const Type& function_type = Type::Handle(Type::Function());
+  const Array& interfaces = Array::Handle(Array::New(1, Heap::kOld));
+  interfaces.SetAt(0, function_type);
+  result.set_interfaces(interfaces);
+  if (!signature_function.IsNull()) {
+    result.PatchSignatureFunction(signature_function);
+  }
+  return result.raw();
+}
+
+
+void Class::PatchSignatureFunction(const Function& signature_function) const {
   ASSERT(!signature_function.IsNull());
   const Class& owner_class = Class::Handle(signature_function.Owner());
   ASSERT(!owner_class.IsNull());
@@ -1923,51 +1952,25 @@
   // A signature class extends class Instance and is parameterized in the same
   // way as the owner class of its non-static signature function.
   // It is not type parameterized if its signature function is static.
+  // In case of a function type alias, the function owner is the alias class
+  // instead of the enclosing class.
   if (!signature_function.is_static() &&
       (owner_class.NumTypeParameters() > 0) &&
       !signature_function.HasInstantiatedSignature()) {
     type_parameters = owner_class.type_parameters();
   }
-  const intptr_t token_pos = signature_function.token_pos();
-  Class& result = Class::Handle(New<Instance>(name, script, token_pos));
-  const Type& super_type = Type::Handle(Type::ObjectType());
-  ASSERT(!super_type.IsNull());
-  result.set_instance_size(Closure::InstanceSize());
-  result.set_next_field_offset(Closure::InstanceSize());
-  result.set_super_type(super_type);
-  result.set_signature_function(signature_function);
-  result.set_type_parameters(type_parameters);
-  result.SetFields(Object::empty_array());
-  result.SetFunctions(Object::empty_array());
-  result.set_type_arguments_field_offset(
-      Closure::type_arguments_offset());
-  // Implements interface "Function".
-  const Type& function_type = Type::Handle(Type::Function());
-  const Array& interfaces = Array::Handle(Array::New(1, Heap::kOld));
-  interfaces.SetAt(0, function_type);
-  result.set_interfaces(interfaces);
-  // Unless the signature function already has a signature class, create a
-  // canonical signature class by having the signature function point back to
-  // the signature class.
-  if (signature_function.signature_class() == Object::null()) {
-    signature_function.set_signature_class(result);
-    result.set_is_finalized();
-  } else {
-    // This new signature class is an alias.
-    ASSERT(!result.IsCanonicalSignatureClass());
-    // Do not yet mark it as finalized, so that the class finalizer can check it
-    // for illegal self references.
-    result.set_is_prefinalized();
+  set_signature_function(signature_function);
+  set_type_parameters(type_parameters);
+  if (owner_class.raw() == raw()) {
+    // This signature class is an alias, which cannot be the canonical
+    // signature class for this signature function.
+    ASSERT(!IsCanonicalSignatureClass());
+  } else if (signature_function.signature_class() == Object::null()) {
+    // Make this signature class the canonical signature class.
+    signature_function.set_signature_class(*this);
+    ASSERT(IsCanonicalSignatureClass());
   }
-  // Instances of a signature class can only be closures.
-  ASSERT(result.instance_size() == Closure::InstanceSize());
-  // Cache the signature type as the first canonicalized type in result.
-  const Type& signature_type = Type::Handle(result.SignatureType());
-  ASSERT(!signature_type.IsFinalized());
-  const Array& new_canonical_types = Array::Handle(Array::New(1, Heap::kOld));
-  new_canonical_types.SetAt(0, signature_type);
-  result.set_canonical_types(new_canonical_types);
-  return result.raw();
+  set_is_prefinalized();
 }
 
 
@@ -3596,8 +3599,8 @@
 }
 
 
-void Function::set_intrinsic_kind(IntrinsicKind value) const {
-  set_kind_tag(IntrinsicKindBits::update(value, raw_ptr()->kind_tag_));
+void Function::set_is_intrinsic(bool value) const {
+  set_kind_tag(IntrinsicBit::update(value, raw_ptr()->kind_tag_));
 }
 
 
@@ -4106,7 +4109,7 @@
   result.set_is_abstract(is_abstract);
   result.set_is_external(is_external);
   result.set_is_visible(true);  // Will be computed later.
-  result.set_intrinsic_kind(kUnknownIntrinsic);
+  result.set_is_intrinsic(false);
   result.set_owner(owner);
   result.set_token_pos(token_pos);
   result.set_end_token_pos(token_pos);
@@ -4213,7 +4216,8 @@
     const Script& script = Script::Handle(this->script());
     signature_class = Class::NewSignatureClass(signature,
                                                closure_function,
-                                               script);
+                                               script,
+                                               closure_function.token_pos());
     library.AddClass(signature_class);
   } else {
     closure_function.set_signature_class(signature_class);
@@ -4238,8 +4242,9 @@
       GrowableObjectArray::Handle(GrowableObjectArray::New());
   String& name = String::Handle();
   if (!instantiate && !is_static() && (name_visibility == kInternalName)) {
-    // Prefix the signature with its class and type parameters, if any (e.g.
-    // "Map<K, V>(K) => bool").
+    // Prefix the signature with its signature class and type parameters, if any
+    // (e.g. "Map<K, V>(K) => bool"). In case of a function type alias, the
+    // signature class name is the alias name.
     // The signature of static functions cannot be type parameterized.
     const Class& function_class = Class::Handle(Owner());
     ASSERT(!function_class.IsNull());
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 81a4f97..0a64f79 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -596,7 +596,7 @@
 
   // Return the signature type of this signature class.
   // For example, if this class represents a signature of the form
-  // '<T, R>(T, [b: B, c: C]) => R', then its signature type is a parameterized
+  // 'F<T, R>(T, [b: B, c: C]) => R', then its signature type is a parameterized
   // type with this class as the type class and type parameters 'T' and 'R'
   // as its type argument vector.
   RawType* SignatureType() const;
@@ -833,9 +833,14 @@
   // The class may be type parameterized unless the signature_function is in a
   // static scope. In that case, the type parameters are copied from the owner
   // class of signature_function.
+  // A null signature function may be passed in and patched later. See below.
   static RawClass* NewSignatureClass(const String& name,
                                      const Function& signature_function,
-                                     const Script& script);
+                                     const Script& script,
+                                     intptr_t token_pos);
+
+  // Patch the signature function of a signature class allocated without it.
+  void PatchSignatureFunction(const Function& signature_function) const;
 
   // Return a class object corresponding to the specified kind. If
   // a canonicalized version of it exists then that object is returned
@@ -1426,16 +1431,10 @@
   }
   void set_is_visible(bool value) const;
 
-  enum IntrinsicKind {
-    kUnknownIntrinsic = 0,  // Initial value.
-    kIsIntrinsic,
-    kIsNotIntrinsic,
-  };
-
-  IntrinsicKind intrinsic_kind() const {
-    return IntrinsicKindBits::decode(raw_ptr()->kind_tag_);
+  bool is_intrinsic() const {
+    return IntrinsicBit::decode(raw_ptr()->kind_tag_);
   }
-  void set_intrinsic_kind(IntrinsicKind value) const;
+  void set_is_intrinsic(bool value) const;
 
   bool HasOptimizedCode() const;
 
@@ -1582,9 +1581,8 @@
     kAbstractBit = 6,
     kExternalBit = 7,
     kVisibleBit = 8,
-    kIntrinsicTagBit = 9,
-    kIntrinsicTagSize = 2,
-    kKindTagBit = 11,
+    kIntrinsicBit = 9,
+    kKindTagBit = 10,
     kKindTagSize = 4,
   };
   class StaticBit : public BitField<bool, kStaticBit, 1> {};
@@ -1596,9 +1594,7 @@
   class AbstractBit : public BitField<bool, kAbstractBit, 1> {};
   class ExternalBit : public BitField<bool, kExternalBit, 1> {};
   class VisibleBit : public BitField<bool, kVisibleBit, 1> {};
-  class IntrinsicKindBits :
-    public BitField<Function::IntrinsicKind,
-                    kIntrinsicTagBit, kIntrinsicTagSize> {};  // NOLINT
+  class IntrinsicBit : public BitField<bool, kIntrinsicBit, 1> {};
   class KindBits :
     public BitField<RawFunction::Kind, kKindTagBit, kKindTagSize> {};  // NOLINT
 
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index a2d6686..e78f306 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -2589,7 +2589,7 @@
   const String& function_name = String::Handle(Symbols::New("foo"));
   function = Function::NewClosureFunction(function_name, parent, 0);
   const Class& signature_class = Class::Handle(
-      Class::NewSignatureClass(function_name, function, script));
+      Class::NewSignatureClass(function_name, function, script, 0));
   const Instance& closure = Instance::Handle(Closure::New(function, context));
   const Class& closure_class = Class::Handle(closure.clazz());
   EXPECT(closure_class.IsSignatureClass());
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 2125da9..3513e79 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -428,6 +428,7 @@
     has_optional_named_parameters = false;
     has_field_initializer = false;
     implicitly_final = false;
+    skipped = false;
     this->parameters = new ZoneGrowableArray<ParamDesc>();
   }
 
@@ -460,6 +461,7 @@
   bool has_optional_named_parameters;
   bool has_field_initializer;
   bool implicitly_final;
+  bool skipped;
   ZoneGrowableArray<ParamDesc>* parameters;
 };
 
@@ -1180,9 +1182,14 @@
       if (signature_class.IsNull()) {
         signature_class = Class::NewSignatureClass(signature,
                                                    signature_function,
-                                                   script_);
-        // Record the function signature class in the current library.
-        library_.AddClass(signature_class);
+                                                   script_,
+                                                   parameter.name_pos);
+        // Record the function signature class in the current library, unless
+        // we are currently skipping a formal parameter list, in which case
+        // the signature class could remain unfinalized.
+        if (!params->skipped) {
+          library_.AddClass(signature_class);
+        }
       } else {
         signature_function.set_signature_class(signature_class);
       }
@@ -2157,7 +2164,7 @@
     const Function& super_ctor = super_call->function();
     // Patch the initializer call so it only executes the super initializer.
     initializer_args->SetNodeAt(1,
-                        new LiteralNode(TokenPos(),
+        new LiteralNode(TokenPos(),
                         Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit))));
 
     ArgumentListNode* super_call_args = new ArgumentListNode(TokenPos());
@@ -3126,6 +3133,7 @@
     OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString());
   }
   Class& cls = Class::Handle();
+  TypeArguments& orig_type_parameters = TypeArguments::Handle();
   Object& obj = Object::Handle(library_.LookupLocalObject(class_name));
   if (obj.IsNull()) {
     if (is_patch) {
@@ -3141,6 +3149,9 @@
     }
     cls ^= obj.raw();
     if (is_patch) {
+      // Preserve and reuse the original type parameters and bounds since the
+      // ones defined in the patch class will not be finalized.
+      orig_type_parameters = cls.type_parameters();
       String& patch = String::Handle(
           String::Concat(Symbols::PatchSpace(), class_name));
       patch = Symbols::New(patch);
@@ -3161,6 +3172,41 @@
   ASSERT(cls.functions() == Object::empty_array().raw());
   set_current_class(cls);
   ParseTypeParameters(cls);
+  if (is_patch) {
+    // Check that the new type parameters are identical to the original ones.
+    const TypeArguments& new_type_parameters =
+        TypeArguments::Handle(cls.type_parameters());
+    const int new_type_params_count =
+        new_type_parameters.IsNull() ? 0 : new_type_parameters.Length();
+    const int orig_type_params_count =
+        orig_type_parameters.IsNull() ? 0 : orig_type_parameters.Length();
+    if (new_type_params_count != orig_type_params_count) {
+      ErrorMsg(classname_pos,
+               "class '%s' must be patched with identical type parameters",
+               class_name.ToCString());
+    }
+    TypeParameter& new_type_param = TypeParameter::Handle();
+    TypeParameter& orig_type_param = TypeParameter::Handle();
+    String& new_name = String::Handle();
+    String& orig_name = String::Handle();
+    for (int i = 0; i < new_type_params_count; i++) {
+      new_type_param ^= new_type_parameters.TypeAt(i);
+      orig_type_param ^= orig_type_parameters.TypeAt(i);
+      new_name = new_type_param.name();
+      orig_name = orig_type_param.name();
+      if (!new_name.Equals(orig_name)) {
+        ErrorMsg(new_type_param.token_pos(),
+                 "type parameter '%s' of patch class '%s' does not match "
+                 "original type parameter '%s'",
+                 new_name.ToCString(),
+                 class_name.ToCString(),
+                 orig_name.ToCString());
+      }
+      // We do not check that the bounds are repeated. We use the original ones.
+      // TODO(regis): Should we check?
+    }
+    cls.set_type_parameters(orig_type_parameters);
+  }
   Type& super_type = Type::Handle();
   if (CurrentToken() == Token::kEXTENDS) {
     ConsumeToken();
@@ -3218,8 +3264,10 @@
   if (!is_patch) {
     pending_classes.Add(cls, Heap::kOld);
   } else {
-    // Lookup the patched class and apply the changes.
-    obj = library_.LookupLocalObject(class_name);
+    // Apply the changes to the patched class looked up above.
+    ASSERT(obj.raw() == library_.LookupLocalObject(class_name));
+    // The patched class must not be finalized yet.
+    ASSERT(!Class::Cast(obj).is_finalized());
     const char* err_msg = Class::Cast(obj).ApplyPatch(cls);
     if (err_msg != NULL) {
       ErrorMsg(classname_pos, "applying patch failed with '%s'", err_msg);
@@ -3330,15 +3378,6 @@
   TRACE_PARSER("ParseFunctionTypeAlias");
   ExpectToken(Token::kTYPEDEF);
 
-  // Allocate an abstract class to hold the type parameters and their bounds.
-  // Make it the owner of the function type descriptor.
-  const Class& alias_owner = Class::Handle(
-      Class::New(Symbols::AliasOwner(), Script::Handle(), TokenPos()));
-
-  alias_owner.set_is_abstract();
-  alias_owner.set_library(library_);
-  set_current_class(alias_owner);
-
   // Parse the result type of the function type.
   AbstractType& result_type = Type::Handle(Type::DynamicType());
   if (CurrentToken() == Token::kVOID) {
@@ -3354,12 +3393,31 @@
   const String* alias_name =
       ExpectUserDefinedTypeIdentifier("function alias name expected");
 
+  // Lookup alias name and report an error if it is already defined in
+  // the library scope.
+  const Object& obj = Object::Handle(library_.LookupLocalObject(*alias_name));
+  if (!obj.IsNull()) {
+    ErrorMsg(alias_name_pos,
+             "'%s' is already defined", alias_name->ToCString());
+  }
+
+  // Create the function type alias signature class. It will be linked to its
+  // signature function after it has been parsed. The type parameters, in order
+  // to be properly finalized, need to be associated to this signature class as
+  // they are parsed.
+  const Class& function_type_alias = Class::Handle(
+      Class::NewSignatureClass(*alias_name,
+                               Function::Handle(),
+                               script_,
+                               alias_name_pos));
+  library_.AddClass(function_type_alias);
+  set_current_class(function_type_alias);
   // Parse the type parameters of the function type.
-  ParseTypeParameters(alias_owner);
+  ParseTypeParameters(function_type_alias);
   // At this point, the type parameters have been parsed, so we can resolve the
   // result type.
   if (!result_type.IsNull()) {
-    ResolveTypeFromClass(alias_owner,
+    ResolveTypeFromClass(function_type_alias,
                          ClassFinalizer::kTryResolve,
                          &result_type);
   }
@@ -3377,6 +3435,7 @@
 
   const bool no_explicit_default_values = false;
   ParseFormalParameterList(no_explicit_default_values, &func_params);
+  ExpectSemicolon();
   // The field 'is_static' has no meaning for signature functions.
   Function& signature_function = Function::Handle(
       Function::New(*alias_name,
@@ -3385,10 +3444,14 @@
                     /* is_const = */ false,
                     /* is_abstract = */ false,
                     /* is_external = */ false,
-                    alias_owner,
+                    function_type_alias,
                     alias_name_pos));
   signature_function.set_result_type(result_type);
   AddFormalParamsToFunction(&func_params, signature_function);
+
+  // Patch the signature function in the signature class.
+  function_type_alias.PatchSignatureFunction(signature_function);
+
   const String& signature = String::Handle(signature_function.Signature());
   if (FLAG_trace_parser) {
     OS::Print("TopLevel parsing function type alias '%s'\n",
@@ -3402,35 +3465,21 @@
   if (signature_class.IsNull()) {
     signature_class = Class::NewSignatureClass(signature,
                                                signature_function,
-                                               script_);
+                                               script_,
+                                               alias_name_pos);
     // Record the function signature class in the current library.
     library_.AddClass(signature_class);
   } else {
     // Forget the just created signature function and use the existing one.
     signature_function = signature_class.signature_function();
+    function_type_alias.PatchSignatureFunction(signature_function);
   }
   ASSERT(signature_function.signature_class() == signature_class.raw());
 
-  // Lookup alias name and report an error if it is already defined in
-  // the library scope.
-  const Object& obj = Object::Handle(library_.LookupLocalObject(*alias_name));
-  if (!obj.IsNull()) {
-    ErrorMsg(alias_name_pos,
-             "'%s' is already defined", alias_name->ToCString());
-  }
-
-  // Create the function type alias, but share the signature function of the
-  // canonical signature class.
-  Class& function_type_alias = Class::Handle(
-      Class::NewSignatureClass(*alias_name,
-                               signature_function,
-                               script_));
-  // This alias should not be marked as finalized yet, since it needs to be
+  // The alias should not be marked as finalized yet, since it needs to be
   // checked in the class finalizer for illegal self references.
   ASSERT(!function_type_alias.IsCanonicalSignatureClass());
   ASSERT(!function_type_alias.is_finalized());
-  library_.AddClass(function_type_alias);
-  ExpectSemicolon();
   pending_classes.Add(function_type_alias, Heap::kOld);
 }
 
@@ -4368,6 +4417,7 @@
       ParseClassDefinition(pending_classes);
     } else if ((CurrentToken() == Token::kTYPEDEF) &&
                (LookaheadToken(1) != Token::kLPAREN)) {
+      set_current_class(toplevel_class);
       ParseFunctionTypeAlias(pending_classes);
     } else if ((CurrentToken() == Token::kABSTRACT) &&
         (LookaheadToken(1) == Token::kCLASS)) {
@@ -4859,7 +4909,8 @@
     ASSERT(is_new_closure);
     signature_class = Class::NewSignatureClass(signature,
                                                function,
-                                               script_);
+                                               script_,
+                                               function.token_pos());
     // Record the function signature class in the current library.
     library_.AddClass(signature_class);
   } else if (is_new_closure) {
@@ -7820,7 +7871,7 @@
     type_arguments = current_class().type_parameters();
   }
   Type& type = Type::ZoneHandle(
-       Type::New(current_class(), type_arguments, type_pos));
+      Type::New(current_class(), type_arguments, type_pos));
   if (!is_top_level_) {
     type ^= ClassFinalizer::FinalizeType(
         current_class(), type, ClassFinalizer::kCanonicalizeWellFormed);
@@ -9435,8 +9486,9 @@
   }
   if (CurrentToken() == Token::kLPAREN) {
     const bool allow_explicit_default_values = true;
-    ParamList ignore_params;
-    ParseFormalParameterList(allow_explicit_default_values, &ignore_params);
+    ParamList params;
+    params.skipped = true;
+    ParseFormalParameterList(allow_explicit_default_values, &params);
   }
   if (CurrentToken() == Token::kLBRACE) {
     SkipBlock();
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 3478c5a..b997520 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -455,6 +455,8 @@
   friend class Object;
   friend class RawInstance;
   friend class RawInstructions;
+  friend class RawType;  // TODO(regis): To temporarily print unfinalized types.
+  friend class RawTypeParameter;  // To temporarily print unfinalized types.
   friend class SnapshotReader;
 };
 
@@ -471,6 +473,8 @@
     return reinterpret_cast<RawObject**>(&ptr()->ident_);
   }
   intptr_t token_pos_;
+
+  friend class RawType;  // TODO(regis): To temporarily print unfinalized types.
 };
 
 
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 8895007..2b4011d 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -11,6 +11,9 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, error_on_malformed_type);
+
+
 #define NEW_OBJECT(type)                                                       \
   ((kind == Snapshot::kFull) ? reader->New##type() : type::New())
 
@@ -112,12 +115,27 @@
 }
 
 
+static const char* RawOneByteStringToCString(RawOneByteString* str) {
+  const char* start = reinterpret_cast<char*>(str) - kHeapObjectTag +
+      OneByteString::data_offset();
+  const int len = Smi::Value(*reinterpret_cast<RawSmi**>(
+      reinterpret_cast<uword>(str) - kHeapObjectTag + String::length_offset()));
+  char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
+  memmove(chars, start, len);
+  chars[len] = '\0';
+  return chars;
+}
+
+
 RawUnresolvedClass* UnresolvedClass::ReadFrom(SnapshotReader* reader,
                                               intptr_t object_id,
                                               intptr_t tags,
                                               Snapshot::Kind kind) {
   ASSERT(reader != NULL);
 
+  // Only resolved and finalized types should be written to a snapshot.
+  // TODO(regis): Replace this code by an UNREACHABLE().
+
   // Allocate parameterized type object.
   UnresolvedClass& unresolved_class = UnresolvedClass::ZoneHandle(
       reader->isolate(), NEW_OBJECT(UnresolvedClass));
@@ -147,6 +165,19 @@
                                  Snapshot::Kind kind) {
   ASSERT(writer != NULL);
 
+  // Only resolved and finalized types should be written to a snapshot.
+  // TODO(regis): Replace this code by an UNREACHABLE().
+  if (FLAG_error_on_malformed_type) {
+    // Print the name of the unresolved class, as well as the token location
+    // from where it is referred to, making sure not to allocate any handles.
+    // Unfortunately, we cannot print the script name.
+    OS::Print("Snapshotting unresolved class '%s' at token pos %"Pd"\n",
+              RawOneByteStringToCString(
+                  reinterpret_cast<RawOneByteString*>(ptr()->ident_)),
+              ptr()->token_pos_);
+    UNREACHABLE();
+  }
+
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
 
@@ -219,6 +250,36 @@
                       Snapshot::Kind kind) {
   ASSERT(writer != NULL);
 
+  // Only resolved and finalized types should be written to a snapshot.
+  // TODO(regis): Replace the test below by an ASSERT().
+  if (FLAG_error_on_malformed_type &&
+      (ptr()->type_state_ != RawType::kFinalizedInstantiated) &&
+      (ptr()->type_state_ != RawType::kFinalizedUninstantiated)) {
+    // Print the name of the class of the unfinalized type, as well as the
+    // token location from where it is referred to, making sure not
+    // to allocate any handles. Unfortunately, we cannot print the script name.
+    const intptr_t cid = ClassIdTag::decode(*reinterpret_cast<uword*>(
+        reinterpret_cast<uword>(ptr()->type_class_) - kHeapObjectTag +
+            Object::tags_offset()));
+    if (cid == kUnresolvedClassCid) {
+      OS::Print("Snapshotting unresolved type '%s' at token pos %"Pd"\n",
+                RawOneByteStringToCString(
+                    reinterpret_cast<RawOneByteString*>(
+                        reinterpret_cast<RawUnresolvedClass*>(
+                            ptr()->type_class_)->ptr()->ident_)),
+                ptr()->token_pos_);
+    } else {
+      // Assume cid == kClassId, but it can also be kIllegalCid.
+      OS::Print("Snapshotting unfinalized type '%s' at token pos %"Pd"\n",
+                RawOneByteStringToCString(
+                    reinterpret_cast<RawOneByteString*>(
+                        reinterpret_cast<RawClass*>(
+                            ptr()->type_class_)->ptr()->name_)),
+                ptr()->token_pos_);
+    }
+    UNREACHABLE();
+  }
+
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
 
@@ -244,7 +305,7 @@
 
   // Allocate type parameter object.
   TypeParameter& type_parameter = TypeParameter::ZoneHandle(
-          reader->isolate(), NEW_OBJECT(TypeParameter));
+      reader->isolate(), NEW_OBJECT(TypeParameter));
   reader->AddBackRef(object_id, &type_parameter, kIsDeserialized);
 
   // Set the object tags.
@@ -274,6 +335,26 @@
                                Snapshot::Kind kind) {
   ASSERT(writer != NULL);
 
+  // Only finalized type parameters should be written to a snapshot.
+  // TODO(regis): Replace the test below by an ASSERT().
+  if (FLAG_error_on_malformed_type &&
+      (ptr()->type_state_ != RawTypeParameter::kFinalizedUninstantiated)) {
+    // Print the name of the unfinalized type parameter, the name of the class
+    // it parameterizes, as well as the token location from where it is referred
+    // to, making sure not to allocate any handles. Unfortunately, we cannot
+    // print the script name.
+    OS::Print("Snapshotting unfinalized type parameter '%s' of class '%s' at "
+              "token pos %"Pd"\n",
+              RawOneByteStringToCString(
+                  reinterpret_cast<RawOneByteString*>(ptr()->name_)),
+              RawOneByteStringToCString(
+                  reinterpret_cast<RawOneByteString*>(
+                      reinterpret_cast<RawClass*>(
+                          ptr()->parameterized_class_)->ptr()->name_)),
+              ptr()->token_pos_);
+    UNREACHABLE();
+  }
+
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
 
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 1069755..70941d9 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -7,6 +7,7 @@
 #include "platform/assert.h"
 #include "vm/bigint_operations.h"
 #include "vm/bootstrap.h"
+#include "vm/class_finalizer.h"
 #include "vm/exceptions.h"
 #include "vm/heap.h"
 #include "vm/longjump.h"
@@ -947,6 +948,7 @@
   ASSERT(isolate != NULL);
   ObjectStore* object_store = isolate->object_store();
   ASSERT(object_store != NULL);
+  ASSERT(ClassFinalizer::AllClassesFinalized());
 
   // Setup for long jump in case there is an exception while writing
   // the snapshot.
@@ -1259,6 +1261,7 @@
   ASSERT(kind() == Snapshot::kScript);
   Isolate* isolate = Isolate::Current();
   ASSERT(isolate != NULL);
+  ASSERT(ClassFinalizer::AllClassesFinalized());
 
   // Setup for long jump in case there is an exception while writing
   // the snapshot.
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index 3628e9b..db65502 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -929,15 +929,17 @@
   {
     TestIsolateScope __test_isolate__;
 
+    Isolate* isolate = Isolate::Current();
+    StackZone zone(isolate);
+    HandleScope scope(isolate);
+
     // Create a test library and Load up a test script in it.
     TestCase::LoadTestScript(kScriptChars, NULL);
+    EXPECT_VALID(Api::CheckIsolateState(isolate));
     timer1.Stop();
     OS::PrintErr("Without Snapshot: %"Pd64"us\n", timer1.TotalElapsedTime());
 
     // Write snapshot with object content.
-    Isolate* isolate = Isolate::Current();
-    StackZone zone(isolate);
-    HandleScope scope(isolate);
     FullSnapshotWriter writer(&buffer, &malloc_allocator);
     writer.WriteFullSnapshot();
   }
@@ -987,7 +989,7 @@
 
     // Create a test library and Load up a test script in it.
     Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
-    ClassFinalizer::FinalizePendingClasses();
+    EXPECT_VALID(Api::CheckIsolateState(isolate));
     timer1.Stop();
     OS::PrintErr("Without Snapshot: %"Pd64"us\n", timer1.TotalElapsedTime());
 
@@ -1104,6 +1106,7 @@
     EXPECT_VALID(Dart_LibraryImportLibrary(TestCase::lib(),
                                            import_lib,
                                            Dart_Null()));
+    EXPECT_VALID(Api::CheckIsolateState(Isolate::Current()));
 
     // Get list of library URLs loaded and save the count.
     Dart_Handle libs = Dart_GetLibraryURLs();
diff --git a/runtime/vm/snapshot_test.dart b/runtime/vm/snapshot_test.dart
index 7e6639d..b42d771 100644
--- a/runtime/vm/snapshot_test.dart
+++ b/runtime/vm/snapshot_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:isolate';
+import 'dart:async';
 
 class Fields {
   Fields(int i, int j) : fld1 = i, fld2 = j, fld5 = true {}
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 660f46f..1ab5563 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -184,7 +184,6 @@
   V(RParenArrow, ") => ")                                                      \
   V(SpaceExtendsSpace, " extends ")                                            \
   V(PatchSpace, "patch ")                                                      \
-  V(AliasOwner, ":alias_owner")                                                \
   V(SwitchExpr, ":switch_expr")                                                \
   V(TwoNewlines, "\n\n")                                                       \
   V(TwoSpaces, "  ")                                                           \
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index 01e5cc2..6bf404e 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -502,23 +502,23 @@
 
   void initializeSpecialClasses() {
     final List missingCoreClasses = [];
-    ClassElement lookupCoreClass(SourceString name) {
-      ClassElement result = coreLibrary.find(name);
+    ClassElement lookupCoreClass(String name) {
+      ClassElement result = coreLibrary.find(new SourceString(name));
       if (result == null) {
-        missingCoreClasses.add(name.slowToString());
+        missingCoreClasses.add(name);
       }
       return result;
     }
-    objectClass = lookupCoreClass(const SourceString('Object'));
-    boolClass = lookupCoreClass(const SourceString('bool'));
-    numClass = lookupCoreClass(const SourceString('num'));
-    intClass = lookupCoreClass(const SourceString('int'));
-    doubleClass = lookupCoreClass(const SourceString('double'));
-    stringClass = lookupCoreClass(const SourceString('String'));
-    functionClass = lookupCoreClass(const SourceString('Function'));
-    listClass = lookupCoreClass(const SourceString('List'));
-    typeClass = lookupCoreClass(const SourceString('Type'));
-    mapClass = lookupCoreClass(const SourceString('Map'));
+    objectClass = lookupCoreClass('Object');
+    boolClass = lookupCoreClass('bool');
+    numClass = lookupCoreClass('num');
+    intClass = lookupCoreClass('int');
+    doubleClass = lookupCoreClass('double');
+    stringClass = lookupCoreClass('String');
+    functionClass = lookupCoreClass('Function');
+    listClass = lookupCoreClass('List');
+    typeClass = lookupCoreClass('Type');
+    mapClass = lookupCoreClass('Map');
     if (!missingCoreClasses.isEmpty) {
       internalErrorOnElement(coreLibrary,
           'dart:core library does not contain required classes: '
@@ -526,18 +526,17 @@
     }
 
     final List missingHelperClasses = [];
-    ClassElement lookupHelperClass(SourceString name) {
-      ClassElement result = jsHelperLibrary.find(name);
+    ClassElement lookupHelperClass(String name) {
+      ClassElement result = jsHelperLibrary.find(new SourceString(name));
       if (result == null) {
-        missingHelperClasses.add(name.slowToString());
+        missingHelperClasses.add(name);
       }
       return result;
     }
-    jsInvocationMirrorClass =
-        lookupHelperClass(const SourceString('JSInvocationMirror'));
-    closureClass = lookupHelperClass(const SourceString('Closure'));
-    dynamicClass = lookupHelperClass(const SourceString('Dynamic_'));
-    nullClass = lookupHelperClass(const SourceString('Null'));
+    jsInvocationMirrorClass = lookupHelperClass('JSInvocationMirror');
+    closureClass = lookupHelperClass('Closure');
+    dynamicClass = lookupHelperClass('Dynamic_');
+    nullClass = lookupHelperClass('Null');
     if (!missingHelperClasses.isEmpty) {
       internalErrorOnElement(jsHelperLibrary,
           'dart:_js_helper library does not contain required classes: '
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index f2e4f8f..c25a335 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -1535,9 +1535,20 @@
     if (closureClass == null) {
       // Either the class was not cached yet, or there are optional parameters.
       // Create a new closure class.
-      SourceString name = const SourceString("BoundClosure");
+      String name;
+      if (canBeShared) {
+        if (inInterceptor) {
+          name = 'BoundClosure\$i${parameterCount}';
+        } else {
+          name = 'BoundClosure\$${parameterCount}';
+        }
+      } else {
+        name = 'Bound_${member.name.slowToString()}'
+            '_${member.enclosingElement.name.slowToString()}';
+      }
+
       ClassElement closureClassElement = new ClosureClassElement(
-          name, compiler, member, member.getCompilationUnit());
+          new SourceString(name), compiler, member, member.getCompilationUnit());
       String mangledName = namer.getName(closureClassElement);
       String superName = namer.getName(closureClassElement.superclass);
       needsClosureClass = true;
@@ -1557,26 +1568,25 @@
 
       String invocationName = namer.instanceMethodName(callElement);
 
-      List<js.Parameter> parameters = <js.Parameter>[];
+      List<String> parameters = <String>[];
       List<js.Expression> arguments = <js.Expression>[];
       if (inInterceptor) {
-        arguments.add(new js.This().dot(fieldNames[2]));
+        arguments.add(js.use('this').dot(fieldNames[2]));
       }
       for (int i = 0; i < parameterCount; i++) {
         String name = 'p$i';
-        parameters.add(new js.Parameter(name));
-        arguments.add(new js.VariableUse(name));
+        parameters.add(name);
+        arguments.add(js.use(name));
       }
 
       js.Expression fun =
-          new js.Fun(parameters,
-              new js.Block(
-                  <js.Statement>[
-                      new js.Return(
-                          new js.PropertyAccess(
-                              new js.This().dot(fieldNames[0]),
-                              new js.This().dot(fieldNames[1]))
-                          .callWith(arguments))]));
+          js.fun(parameters,
+              js.block1(
+                  js.return_(
+                      new js.PropertyAccess(
+                          js.use('this').dot(fieldNames[0]),
+                          js.use('this').dot(fieldNames[1]))
+                      .callWith(arguments))));
       boundClosureBuilder.addProperty(invocationName, fun);
 
       addParameterStubs(callElement, boundClosureBuilder.addProperty);
@@ -1604,23 +1614,20 @@
     String getterName = namer.getterName(member);
     String targetName = namer.instanceMethodName(member);
 
-    List<js.Parameter> parameters = <js.Parameter>[];
+    List<String> parameters = <String>[];
     List<js.Expression> arguments = <js.Expression>[];
-    arguments.add(new js.This());
+    arguments.add(js.use('this'));
     arguments.add(js.string(targetName));
     if (inInterceptor) {
-      parameters.add(new js.Parameter(extraArg));
-      arguments.add(new js.VariableUse(extraArg));
+      parameters.add(extraArg);
+      arguments.add(js.use(extraArg));
     }
 
     js.Expression getterFunction =
-        new js.Fun(parameters,
-            new js.Block(
-                <js.Statement>[
-                    new js.Return(
-                        new js.New(
-                            new js.VariableUse(closureClass),
-                            arguments))]));
+        js.fun(parameters,
+            js.block1(
+                js.return_(
+                    new js.New(js.use(closureClass), arguments))));
 
     defineStub(getterName, getterFunction);
   }
diff --git a/sdk/lib/_internal/compiler/implementation/lib/isolate_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/isolate_patch.dart
index a8d3c27..aab847a 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/isolate_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/isolate_patch.dart
@@ -9,19 +9,19 @@
                                    ReceivePortImpl;
 
 patch class _Isolate {
-  patch ReceivePort get port {
+  patch static ReceivePort get port {
     if (lazyPort == null) {
       lazyPort = new ReceivePort();
     }
     return lazyPort;
   }
 
-  patch SendPort spawnFunction(void topLevelFunction(),
+  patch static SendPort spawnFunction(void topLevelFunction(),
       [bool UnhandledExceptionCallback(IsolateUnhandledException e)]) {
     return IsolateNatives.spawnFunction(topLevelFunction);
   }
 
-  patch SendPort spawnUri(String uri) {
+  patch static SendPort spawnUri(String uri) {
     return IsolateNatives.spawn(null, uri, false);
   }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_array.dart b/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
index 3491591..fad48f0 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
@@ -85,7 +85,7 @@
   }
 
   Iterable map(f(E element)) {
-    return IterableMixinWorkaround.map(this, f);
+    return IterableMixinWorkaround.mapList(this, f);
   }
 
   List mappedBy(f(E element)) {
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_string.dart b/sdk/lib/_internal/compiler/implementation/lib/js_string.dart
index d0d857c..381a690 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_string.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_string.dart
@@ -13,7 +13,9 @@
 class JSString implements String {
   const JSString();
 
-  int charCodeAt(index) {
+  int charCodeAt(index) => codeUnitAt(index);
+
+  int codeUnitAt(int index) {
     if (index is !num) throw new ArgumentError(index);
     if (index < 0) throw new RangeError.value(index);
     if (index >= length) throw new RangeError.value(index);
@@ -147,6 +149,14 @@
     return result;
   }
 
+  Iterable<int> get codeUnits {
+    throw new UnimplementedError("String.codeUnits");
+  }
+
+  Iterable<int> get runes {
+    throw new UnimplementedError("String.runes");
+  }
+
   int indexOf(String other, [int start = 0]) {
     checkNull(other);
     if (start is !int) throw new ArgumentError(start);
diff --git a/sdk/lib/_internal/compiler/implementation/native_handler.dart b/sdk/lib/_internal/compiler/implementation/native_handler.dart
index 933e96d..5640670 100644
--- a/sdk/lib/_internal/compiler/implementation/native_handler.dart
+++ b/sdk/lib/_internal/compiler/implementation/native_handler.dart
@@ -51,6 +51,8 @@
   /// Computes types instantiated due to setting a native field.
   void registerFieldStore(Element field) {}
 
+  NativeBehavior getNativeBehaviorOf(Send node) => null;
+
   /**
    * Handles JS-calls, which can be an instantiation point for types.
    *
@@ -91,6 +93,9 @@
   final queue = new Queue();
   bool flushing = false;
 
+  /// Maps JS foreign calls to their computed native behavior.
+  final Map<Node, NativeBehavior> nativeBehaviors =
+      new Map<Node, NativeBehavior>();
 
   final Enqueuer world;
   final Compiler compiler;
@@ -302,12 +307,14 @@
   }
 
   void registerJsCall(Send node, ResolverVisitor resolver) {
-    processNativeBehavior(
-        NativeBehavior.ofJsCall(node, compiler, resolver),
-        node);
+    NativeBehavior behavior = NativeBehavior.ofJsCall(node, compiler, resolver);
+    processNativeBehavior(behavior, node);
+    nativeBehaviors[node] = behavior;
     flushQueue();
   }
 
+  NativeBehavior getNativeBehaviorOf(Send node) => nativeBehaviors[node];
+
   processNativeBehavior(NativeBehavior behavior, cause) {
     bool allUsedBefore = unusedClasses.isEmpty;
     for (var type in behavior.typesInstantiated) {
@@ -881,8 +888,7 @@
     }
 
     DartString jsCode = new DartString.literal(nativeMethodCall);
-    builder.push(
-        new HForeign(jsCode, const LiteralDartString('Object'), inputs));
+    builder.push(new HForeign(jsCode, HType.UNKNOWN, inputs));
     builder.close(new HReturn(builder.pop())).addSuccessor(builder.graph.exit);
   } else {
     if (parameters.parameterCount != 0) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 67085fd..5ae62cb 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -179,7 +179,7 @@
     // TODO(floitsch): Clean up this hack. Should we create a box-object by
     // just creating an empty object literal?
     HInstruction box = new HForeign(const LiteralDartString("{}"),
-                                    const LiteralDartString('Object'),
+                                    HType.UNKNOWN,
                                     <HInstruction>[]);
     builder.add(box);
     return box;
@@ -1358,11 +1358,14 @@
         includeBackendMembers: true,
         includeSuperMembers: true);
 
-    HForeignNew newObject = new HForeignNew(classElement, constructorArguments);
+    InterfaceType type = classElement.computeType(compiler);
+    HType ssaType = new HBoundedType.exact(type);
+    HForeignNew newObject = new HForeignNew(classElement,
+                                            ssaType,
+                                            constructorArguments);
     add(newObject);
 
     // Create the runtime type information, if needed.
-    InterfaceType type = classElement.computeType(compiler);
     List<HInstruction> inputs = <HInstruction>[];
     if (compiler.world.needsRti(classElement)) {
       classElement.typeVariables.forEach((TypeVariableType typeVariable) {
@@ -2145,7 +2148,9 @@
       }
     });
 
-    push(new HForeignNew(closureClassElement, capturedVariables));
+    HType type = new HBoundedType.exact(
+        compiler.functionClass.computeType(compiler));
+    push(new HForeignNew(closureClassElement, type, capturedVariables));
   }
 
   visitFunctionDeclaration(FunctionDeclaration node) {
@@ -2539,10 +2544,8 @@
     push(result);
   }
 
-  HForeign createForeign(String code, String type, List<HInstruction> inputs) {
-    return new HForeign(new LiteralDartString(code),
-                        new LiteralDartString(type),
-                        inputs);
+  HForeign createForeign(String code, HType type, List<HInstruction> inputs) {
+    return new HForeign(new LiteralDartString(code), type, inputs);
   }
 
   HInstruction getRuntimeTypeInfo(HInstruction target) {
@@ -2554,7 +2557,7 @@
   // (dartbug.com/7182).
   List<HInstruction> buildTypeArgumentRepresentations(DartType type) {
     HInstruction createForeignArray(String code, inputs) {
-      return createForeign(code, '=List', inputs);
+      return createForeign(code, HType.READABLE_ARRAY, inputs);
     }
     HInstruction typeInfo;
 
@@ -2654,7 +2657,7 @@
           HInstruction position = graph.addConstantInt(index, constantSystem);
           // Get the index'th type argument from the runtime type information.
           HInstruction typeArgument =
-              createForeign('#[#]', 'Object', [typeInfo, position]);
+              createForeign('#[#]', HType.UNKNOWN, [typeInfo, position]);
           add(typeArgument);
           // Create the call to isSubtype.
           List<HInstruction> inputs =
@@ -2852,26 +2855,6 @@
     pushWithPosition(new HInvokeClosure(closureSelector, inputs), node);
   }
 
-  void registerForeignTypes(String specString) {
-    CodegenEnqueuer enqueuer = compiler.enqueuer.codegen;
-    for (final typeString in specString.split('|')) {
-      if (typeString == '=List') {
-        enqueuer.registerInstantiatedClass(compiler.listClass);
-      } else if (typeString == 'int') {
-        enqueuer.registerInstantiatedClass(compiler.intClass);
-      } else if (typeString == 'double') {
-        enqueuer.registerInstantiatedClass(compiler.doubleClass);
-      } else if (typeString == 'num') {
-        enqueuer.registerInstantiatedClass(compiler.intClass);
-        enqueuer.registerInstantiatedClass(compiler.doubleClass);
-      } else if (typeString == 'Null') {
-        enqueuer.registerInstantiatedClass(compiler.nullClass);
-      } else if (typeString == 'String') {
-        enqueuer.registerInstantiatedClass(compiler.stringClass);
-      }
-    }
-  }
-
   void handleForeignJs(Send node) {
     Link<Node> link = node.arguments;
     // If the invoke is on foreign code, don't visit the first
@@ -2886,24 +2869,14 @@
     Node code = link.tail.head;
     addGenericSendArgumentsToList(link.tail.tail, inputs);
 
-    if (type is !LiteralString) {
-      // The type must not be a juxtaposition or interpolation.
-      compiler.cancel('The type of a JS expression must be a string literal',
-                      node: type);
-    }
-    LiteralString typeString = type;
-    // TODO(ngeoffray): This should be registered in codegen, not here.
-    // Also, we should share the type parsing with the native
-    // enqueuer.
-    registerForeignTypes(typeString.dartString.slowToString());
-
+    native.NativeBehavior nativeBehavior =
+        compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
+    HType ssaType = mapNativeBehaviorType(nativeBehavior);
     if (code is StringNode) {
       StringNode codeString = code;
       if (!codeString.isInterpolation) {
         // codeString may not be an interpolation, but may be a juxtaposition.
-        push(new HForeign(codeString.dartString,
-                          typeString.dartString,
-                          inputs));
+        push(new HForeign(codeString.dartString, ssaType, inputs));
         return;
       }
     }
@@ -2921,7 +2894,7 @@
       // to fetch the Leg's current isolate.
       String name = backend.namer.CURRENT_ISOLATE;
       push(new HForeign(new DartString.literal(name),
-                        const LiteralDartString('var'),
+                        HType.UNKNOWN,
                         <HInstruction>[]));
     } else {
       // Call a helper method from the isolate library. The isolate
@@ -2994,7 +2967,7 @@
     String invocationName = backend.namer.invocationName(
         new Selector.callClosure(params.requiredParameterCount));
     push(new HForeign(new DartString.literal('#.$invocationName'),
-                      const LiteralDartString('var'),
+                      HType.UNKNOWN,
                       inputs));
   }
 
@@ -3006,7 +2979,7 @@
     visit(node.arguments.head);
     String isolateName = backend.namer.CURRENT_ISOLATE;
     push(new HForeign(new DartString.literal("$isolateName = #"),
-                      const LiteralDartString('void'),
+                      HType.UNKNOWN,
                       <HInstruction>[pop()]));
   }
 
@@ -3017,7 +2990,7 @@
     }
     String constructorName = backend.namer.isolateName;
     push(new HForeign(new DartString.literal("new $constructorName"),
-                      const LiteralDartString('var'),
+                      HType.UNKNOWN,
                       <HInstruction>[]));
   }
 
@@ -3184,7 +3157,7 @@
           typeInfo = pop();
         }
         int index = RuntimeTypeInformation.getTypeVariableIndex(type);
-        HInstruction foreign = createForeign('#[$index]', 'String',
+        HInstruction foreign = createForeign('#[$index]', HType.STRING,
                                              <HInstruction>[typeInfo]);
         add(foreign);
         inputs.add(foreign);
@@ -3198,7 +3171,7 @@
 
     String template = rti.getTypeRepresentation(argument,
                                                 addTypeVariableReference);
-    HInstruction result = createForeign(template, 'String', inputs);
+    HInstruction result = createForeign(template, HType.STRING, inputs);
     add(result);
     return result;
   }
@@ -4610,17 +4583,43 @@
     compiler.internalError('SsaBuilder.visitTypeVariable');
   }
 
+  HType mapBaseType(BaseType baseType) {
+    if (!baseType.isClass()) return HType.UNKNOWN;
+    ClassBaseType classBaseType = baseType;
+    return new HType.fromBoundedType(
+        classBaseType.element.computeType(compiler), compiler, false);
+  }
+
   HType mapInferredType(ConcreteType concreteType) {
     if (concreteType == null) return HType.UNKNOWN;
-    ClassElement element = concreteType.getUniqueType();
-    if (element == null) return HType.UNKNOWN;
-    if (element == builder.compiler.boolClass) return HType.BOOLEAN;
-    if (element == builder.compiler.doubleClass) return HType.DOUBLE;
-    if (element == builder.compiler.intClass) return HType.INTEGER;
-    if (element == builder.compiler.listClass) return HType.READABLE_ARRAY;
-    if (element == builder.compiler.nullClass) return HType.NULL;
-    if (element == builder.compiler.stringClass) return HType.STRING;
-    return HType.UNKNOWN;
+    HType ssaType = HType.CONFLICTING;
+    for (BaseType baseType in concreteType.baseTypes) {
+      ssaType = ssaType.union(mapBaseType(baseType), compiler);
+    }
+    assert(!ssaType.isConflicting());
+    return ssaType;
+  }
+
+  HType mapNativeType(type) {
+    if (type == native.SpecialType.JsObject) {
+      return new HBoundedType.exact(
+          compiler.objectClass.computeType(compiler));
+    } else if (type == native.SpecialType.JsArray) {
+      return HType.READABLE_ARRAY;
+    } else {
+      return new HType.fromBoundedType(type, compiler, false);
+    }
+  }
+
+  HType mapNativeBehaviorType(native.NativeBehavior nativeBehavior) {
+    if (nativeBehavior.typesInstantiated.isEmpty) return HType.UNKNOWN;
+
+    HType ssaType = HType.CONFLICTING;
+    for (final type in nativeBehavior.typesInstantiated) {
+      ssaType = ssaType.union(mapNativeType(type), compiler);
+    }
+    assert(!ssaType.isConflicting());
+    return ssaType;
   }
 }
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index eeaad2a..8164118 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -1765,6 +1765,15 @@
     assignVariable(variableNames.getName(node.receiver), pop());
   }
 
+  void registerForeignType(HType type) {
+    DartType dartType = type.computeType(compiler);
+    if (dartType == null) {
+      assert(type == HType.UNKNOWN);
+      return;
+    }
+    world.registerInstantiatedClass(dartType.element);
+  }
+
   visitForeign(HForeign node) {
     String code = node.code.slowToString();
     List<HInstruction> inputs = node.inputs;
@@ -1782,10 +1791,7 @@
       }
       push(new js.LiteralExpression.withData(code, data), node);
     }
-    DartType type = types[node].computeType(compiler);
-    if (type != null) {
-      world.registerInstantiatedClass(type.element);
-    }
+    registerForeignType(types[node]);
     // TODO(sra): Tell world.nativeEnqueuer about the types created here.
   }
 
@@ -1801,6 +1807,7 @@
     // TODO(floitsch): jsClassReference is an Access. We shouldn't treat it
     // as if it was a string.
     push(new js.New(new js.VariableUse(jsClassReference), arguments), node);
+    registerForeignType(types[node]);
   }
 
   js.Expression newLiteralBool(bool value) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index 2876e06..21b3d71 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -1543,46 +1543,33 @@
 
 class HForeign extends HInstruction {
   final DartString code;
-  final HType foreignType;
+  final HType type;
   final bool isStatement;
 
   HForeign(this.code,
-           DartString declaredType,
+           this.type,
            List<HInstruction> inputs,
            {this.isStatement: false})
-      : foreignType = computeTypeFromDeclaredType(declaredType),
-        super(inputs) {
+      : super(inputs) {
     setAllSideEffects();
     setDependsOnSomething();
   }
 
   HForeign.statement(code, List<HInstruction> inputs)
-      : this(code, const LiteralDartString('var'), inputs, isStatement: true);
+      : this(code, HType.UNKNOWN, inputs, isStatement: true);
 
   accept(HVisitor visitor) => visitor.visitForeign(this);
 
-  static HType computeTypeFromDeclaredType(DartString declaredType) {
-    if (declaredType.slowToString() == 'bool') return HType.BOOLEAN;
-    if (declaredType.slowToString() == 'int') return HType.INTEGER;
-    if (declaredType.slowToString() == 'double') return HType.DOUBLE;
-    if (declaredType.slowToString() == 'num') return HType.NUMBER;
-    if (declaredType.slowToString() == 'String') return HType.STRING;
-    if (declaredType.slowToString() == '=List') return HType.READABLE_ARRAY;
-    return HType.UNKNOWN;
-  }
-
-  HType get guaranteedType => foreignType;
+  HType get guaranteedType => type;
 
   bool isJsStatement() => isStatement;
   bool canThrow() => true;
-
 }
 
 class HForeignNew extends HForeign {
   ClassElement element;
-  HForeignNew(this.element, List<HInstruction> inputs)
-      : super(const LiteralDartString("new"),
-              const LiteralDartString("Object"), inputs);
+  HForeignNew(this.element, HType type, List<HInstruction> inputs)
+      : super(const LiteralDartString("new"), type, inputs);
   accept(HVisitor visitor) => visitor.visitForeignNew(this);
 }
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types.dart b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
index 12800ab..06e432e 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
@@ -15,30 +15,32 @@
                                 Compiler compiler,
                                 [bool canBeNull = false]) {
     Element element = type.element;
-    if (identical(element.kind, ElementKind.TYPE_VARIABLE)) {
+    if (element.kind == ElementKind.TYPE_VARIABLE) {
       // TODO(ngeoffray): Replace object type with [type].
       return new HBoundedPotentialPrimitiveType(
           compiler.objectClass.computeType(compiler), canBeNull, true);
     }
 
-    if (identical(element, compiler.intClass)) {
+    if (element == compiler.intClass) {
       return canBeNull ? HType.INTEGER_OR_NULL : HType.INTEGER;
-    } else if (identical(element, compiler.numClass)) {
+    } else if (element == compiler.numClass) {
       return canBeNull ? HType.NUMBER_OR_NULL : HType.NUMBER;
-    } else if (identical(element, compiler.doubleClass)) {
+    } else if (element == compiler.doubleClass) {
       return canBeNull ? HType.DOUBLE_OR_NULL : HType.DOUBLE;
-    } else if (identical(element, compiler.stringClass)) {
+    } else if (element == compiler.stringClass) {
       return canBeNull ? HType.STRING_OR_NULL : HType.STRING;
-    } else if (identical(element, compiler.boolClass)) {
+    } else if (element == compiler.boolClass) {
       return canBeNull ? HType.BOOLEAN_OR_NULL : HType.BOOLEAN;
-    } else if (identical(element, compiler.listClass)
+    } else if (element == compiler.nullClass) {
+      return HType.NULL;
+    } else if (element == compiler.listClass
         || Elements.isListSupertype(element, compiler)) {
       return new HBoundedPotentialPrimitiveArray(type, canBeNull);
     } else if (Elements.isNumberOrStringSupertype(element, compiler)) {
       return new HBoundedPotentialPrimitiveNumberOrString(type, canBeNull);
     } else if (Elements.isStringOnlySupertype(element, compiler)) {
       return new HBoundedPotentialPrimitiveString(type, canBeNull);
-    } else if (identical(element, compiler.objectClass)) {
+    } else if (element == compiler.objectClass) {
       return new HBoundedPotentialPrimitiveType(
           compiler.objectClass.computeType(compiler), canBeNull, true);
     } else {
@@ -170,7 +172,9 @@
   bool isNull() => true;
   String toString() => 'null';
 
-  DartType computeType(Compiler compiler) => null;
+  DartType computeType(Compiler compiler) {
+    return compiler.nullClass.computeType(compiler);
+  }
 
   HType union(HType other, Compiler compiler) {
     if (other.isConflicting()) return HType.NULL;
@@ -180,6 +184,8 @@
     if (other.isDouble()) return HType.DOUBLE_OR_NULL;
     if (other.isNumber()) return HType.NUMBER_OR_NULL;
     if (other.isBoolean()) return HType.BOOLEAN_OR_NULL;
+    // TODO(ngeoffray): Deal with the type of null more generally.
+    if (other.isReadableArray()) return other.union(this, compiler);
     if (!other.canBeNull()) return HType.UNKNOWN;
     return other;
   }
@@ -597,6 +603,11 @@
     if (other.isReadableArray()) return HType.READABLE_ARRAY;
     if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE;
     if (other is HBoundedPotentialPrimitiveArray) return other;
+    if (other.isNull()) {
+      // TODO(ngeoffray): This should be readable array or null.
+      return new HBoundedPotentialPrimitiveArray(
+          compiler.listClass.computeType(compiler), true);
+    }
     return HType.UNKNOWN;
   }
 
@@ -623,6 +634,11 @@
     if (other.isReadableArray()) return HType.READABLE_ARRAY;
     if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE;
     if (other is HBoundedPotentialPrimitiveArray) return other;
+    if (other.isNull()) {
+      // TODO(ngeoffray): This should be mutable array or null.
+      return new HBoundedPotentialPrimitiveArray(
+          compiler.listClass.computeType(compiler), true);
+    }
     return HType.UNKNOWN;
   }
 
@@ -650,6 +666,11 @@
     if (other.isReadableArray()) return HType.READABLE_ARRAY;
     if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE;
     if (other is HBoundedPotentialPrimitiveArray) return other;
+    if (other.isNull()) {
+      // TODO(ngeoffray): This should be fixed array or null.
+      return new HBoundedPotentialPrimitiveArray(
+          compiler.listClass.computeType(compiler), true);
+    }
     return HType.UNKNOWN;
   }
 
@@ -678,6 +699,11 @@
     if (other.isReadableArray()) return HType.READABLE_ARRAY;
     if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE;
     if (other is HBoundedPotentialPrimitiveArray) return other;
+    if (other.isNull()) {
+      // TODO(ngeoffray): This should be extendable array or null.
+      return new HBoundedPotentialPrimitiveArray(
+          compiler.listClass.computeType(compiler), true);
+    }
     return HType.UNKNOWN;
   }
 
diff --git a/sdk/lib/_internal/compiler/samples/leap/leap_server.dart b/sdk/lib/_internal/compiler/samples/leap/leap_server.dart
index adf8cbc..e4f2811 100644
--- a/sdk/lib/_internal/compiler/samples/leap/leap_server.dart
+++ b/sdk/lib/_internal/compiler/samples/leap/leap_server.dart
@@ -2,6 +2,8 @@
 // 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.
 
+library leap_server;
+
 import 'dart:io';
 
 class Conversation {
@@ -39,7 +41,7 @@
     String path = request.path;
     if (path == '/') return redirect('/$landingPage');
     if (path == '/favicon.ico') {
-      path = '/lib/_internal/dartdoc/static/favicon.ico';
+      path = '/sdk/lib/_internal/dartdoc/static/favicon.ico';
     }
     if (path.contains('..') || path.contains('%')) return notFound();
     var f = new File("./$path");
diff --git a/sdk/lib/collection/collections.dart b/sdk/lib/collection/collections.dart
index 0c45e21..369a3d3 100644
--- a/sdk/lib/collection/collections.dart
+++ b/sdk/lib/collection/collections.dart
@@ -317,6 +317,10 @@
     return new MappedIterable(iterable, f);
   }
 
+  static Iterable mapList(List list, f(var element)) {
+    return new MappedListIterable(list, f, 0, null);
+  }
+
   static List mappedByList(List list, f(var element)) {
     // This is currently a List as well as an Iterable.
     return new MappedList(list, f);
diff --git a/sdk/lib/collection_dev/iterable.dart b/sdk/lib/collection_dev/iterable.dart
index 8fcef18..9729e1c 100644
--- a/sdk/lib/collection_dev/iterable.dart
+++ b/sdk/lib/collection_dev/iterable.dart
@@ -21,6 +21,7 @@
   bool get isEmpty => _iterable.isEmpty;
 }
 
+
 class MappedIterator<S, T> extends Iterator<T> {
   T _current;
   final Iterator<S> _iterator;
@@ -43,6 +44,334 @@
   T get current => _current;
 }
 
+/** Specialized alternative to [MappedIterable] for mapped [List]s. */
+class MappedListIterable<S, T> extends Iterable<T> {
+  final List<S> _list;
+  /**
+   * Start index of the part of the list to map.
+   *
+   * Allows mapping only a sub-list of an existing list.
+   *
+   * Used to implement lazy skip/take on a [MappedListIterable].
+   */
+  final int _start;
+
+  /**
+   * End index of the part of the list to map.
+   *
+   * If null, always use the length of the list.
+   */
+  final int _end;
+
+  // TODO(ahe): Restore type when feature is implemented in dart2js
+  // checked mode. http://dartbug.com/7733
+  final /* _Transformation<S, T> */ _f;
+
+  MappedListIterable(this._list, T this._f(S element), this._start, this._end) {
+    if (_end != null && _end < _start) {
+      throw new ArgumentError("End ($_end) before start ($_start)");
+    }
+  }
+
+  /** The start index, limited to the current length of the list. */
+  int get _startIndex {
+    if (_start <= _list.length) return _start;
+    return _list.length;
+  }
+
+  /** The end index, if given, limited to the current length of the list. */
+  int get _endIndex {
+    if (_end == null || _end > _list.length) return _list.length;
+    return _end;
+  }
+
+  Iterator<T> get iterator =>
+      new MappedListIterator<S, T>(_list, _f, _startIndex, _endIndex);
+
+  void forEach(void action(T element)) {
+    int length = _list.length;
+    for (int i = _startIndex, n = _endIndex; i < n; i++) {
+      action(_f(_list[i]));
+      if (_list.length != length) {
+        throw new ConcurrentModificationError(_list);
+      }
+    }
+  }
+
+  bool get isEmpty => _startIndex == _endIndex;
+
+  int get length => _endIndex - _startIndex;
+
+  T get first {
+    int start = _startIndex;
+    if (start == _endIndex) {
+      throw new StateError("No elements");
+    }
+    return _f(_list.elementAt(start));
+  }
+
+  T get last {
+    int end = _endIndex;
+    if (end == _startIndex) {
+      throw new StateError("No elements");
+    }
+    return _f(_list.elementAt(end - 1));
+  }
+
+  T get single {
+    int start = _startIndex;
+    int end = _endIndex;
+    if (start != end - 1) {
+      if (start == end) {
+        throw new StateError("No elements");
+      }
+      throw new StateError("Too many elements");
+    }
+    return _f(_list[start]);
+  }
+
+  T elementAt(int index) {
+    index += _startIndex;
+    if (index >= _endIndex) {
+      throw new StateError("No matching element");
+    }
+    return _f(_list.elementAt(index));
+  }
+
+  bool contains(T element) {
+    int length = _list.length;
+    for (int i = _startIndex, n = _endIndex; i < n; i++) {
+      if (_f(_list[i]) == element) {
+        return true;
+      }
+      if (_list.length != length) {
+        throw new ConcurrentModificationError(_list);
+      }
+    }
+    return false;
+  }
+
+  bool every(bool test(T element)) {
+    int length = _list.length;
+    for (int i = _startIndex, n = _endIndex; i < n; i++) {
+      if (!test(_f(_list[i]))) return false;
+      if (_list.length != length) {
+        throw new ConcurrentModificationError(_list);
+      }
+    }
+    return true;
+  }
+
+  bool any(bool test(T element)) {
+    int length = _list.length;
+    for (int i = _startIndex, n = _endIndex; i < n; i++) {
+      if (test(_f(_list[i]))) return true;
+      if (_list.length != length) {
+        throw new ConcurrentModificationError(_list);
+      }
+    }
+    return false;
+  }
+
+  T firstMatching(bool test(T element), { T orElse() }) {
+    int length = _list.length;
+    for (int i = _startIndex, n = _endIndex; i < n; i++) {
+      T value = _f(_list[i]);
+      if (test(value)) return value;
+      if (_list.length != length) {
+        throw new ConcurrentModificationError(_list);
+      }
+    }
+    if (orElse != null) return orElse();
+    throw new StateError("No matching element");
+  }
+
+  T lastMatching(bool test(T element), { T orElse() }) {
+    int length = _list.length;
+    for (int i = _endIndex - 1, start = _startIndex; i >= start; i++) {
+      T value = _f(_list[i]);
+      if (test(value)) return value;
+      if (_list.length != length) {
+        throw new ConcurrentModificationError(_list);
+      }
+    }
+    if (orElse != null) return orElse();
+    throw new StateError("No matching element");
+  }
+
+  T singleMatching(bool test(T element)) {
+    int length = _list.length;
+    T match;
+    bool matchFound = false;
+    for (int i = _startIndex, n = _endIndex; i < n; i++) {
+      T value = _f(_list[i]);
+      if (test(value)) {
+        if (matchFound) {
+          throw new StateError("More than one matching element");
+        }
+        matchFound = true;
+        match = value;
+      }
+      if (_list.length != length) {
+        throw new ConcurrentModificationError(_list);
+      }
+    }
+    if (matchFound) return match;
+    throw new StateError("No matching element");
+  }
+
+  T min([int compare(T a, T b)]) {
+    if (compare == null) {
+      var defaultCompare = Comparable.compare;
+      compare = defaultCompare;
+    }
+    int length = _list.length;
+    int start = _startIndex;
+    int end = _endIndex;
+    if (start == end) return null;
+    T value = _f(_list[start]);
+    if (_list.length != length) {
+      throw new ConcurrentModificationError(_list);
+    }
+    for (int i = start + 1; i < end; i++) {
+      T nextValue = _f(_list[i]);
+      if (compare(value, nextValue) > 0) {
+        value = nextValue;
+      }
+      if (_list.length != length) {
+        throw new ConcurrentModificationError(_list);
+      }
+    }
+    return value;
+  }
+
+  T max([int compare(T a, T b)]) {
+    if (compare == null) {
+      var defaultCompare = Comparable.compare;
+      compare = defaultCompare;
+    }
+    int length = _list.length;
+    int start = _startIndex;
+    int end = _endIndex;
+    if (start == end) return null;
+    T value = _f(_list[start]);
+    if (_list.length != length) {
+      throw new ConcurrentModificationError(_list);
+    }
+    for (int i = start + 1; i < end; i++) {
+      T nextValue = _f(_list[i]);
+      if (compare(value, nextValue) < 0) {
+        value = nextValue;
+      }
+      if (_list.length != length) {
+        throw new ConcurrentModificationError(_list);
+      }
+    }
+    return value;
+  }
+
+  String join([String separator]) {
+    int start = _startIndex;
+    int end = _endIndex;
+    if (start == end) return "";
+    StringBuffer buffer = new StringBuffer("${_f(_list[start])}");
+    if (_list.length != length) {
+      throw new ConcurrentModificationError(_list);
+    }
+    for (int i = start + 1; i < end; i++) {
+      buffer.add(separator);
+      buffer.add("${_f(_list[i])}");
+      if (_list.length != length) {
+        throw new ConcurrentModificationError(_list);
+      }
+    }
+    return buffer.toString();
+  }
+
+  Iterable<T> where(bool test(T element)) => super.where(test);
+
+  Iterable map(f(T element)) {
+    return new MappedListIterable(_list, (S v) => f(_f(v)), _start, _end);
+  }
+
+  Iterable mappedBy(f(T element)) => map(f);
+
+  reduce(var initialValue, combine(var previousValue, T element)) {
+    return _list.reduce(initialValue, (v, S e) => combine(v, _f(e)));
+  }
+
+  Iterable<T> skip(int count) {
+    int start = _startIndex + count;
+    if (_end != null && start >= _end) {
+      return new EmptyIterable<T>();
+    }
+    return new MappedListIterable(_list, _f, start, _end);
+  }
+
+  Iterable<T> skipWhile(bool test(T element)) => super.skipWhile(test);
+
+  Iterable<T> take(int count)  {
+    int newEnd = _start + count;
+    if (_end == null || newEnd < _end)  {
+      return new MappedListIterable(_list, _f, _start, newEnd);
+    }
+    // Equivalent to "this".
+    return new MappedListIterable(_list, _f, _start, _end);
+  }
+
+  Iterable<T> takeWhile(bool test(T element)) => super.takeWhile(test);
+
+  List<T> toList() {
+    List<T> result = new List<T>();
+    forEach(result.add);
+    return result;
+  }
+
+  Set<T> toSet() {
+    Set<T> result = new Set<T>();
+    forEach(result.add);
+    return result;
+  }
+}
+
+/**
+ * Iterator for [MappedListIterable].
+ *
+ * A list iterator that iterates over (a sublist of) a list and
+ * returns the values transformed by a function.
+ *
+ * As a list iterator, it throws if the length of the list has
+ * changed during iteration.
+ */
+class MappedListIterator<S, T> implements Iterator<T> {
+  List<S> _list;
+  // TODO(ahe): Restore type when feature is implemented in dart2js
+  // checked mode. http://dartbug.com/7733
+  final /* _Transformation<S, T> */ _f;
+  final int _endIndex;
+  final int _length;
+  int _index;
+  T _current;
+
+  MappedListIterator(List<S> list, this._f, int start, this._endIndex)
+      : _list = list, _length = list.length, _index = start;
+
+  T get current => _current;
+
+  bool moveNext() {
+    if (_list.length != _length) {
+      throw new ConcurrentModificationError(_list);
+    }
+    if (_index >= _endIndex) {
+      _current = null;
+      return false;
+    }
+    _current = _f(_list[_index]);
+    _index++;
+    return true;
+  }
+}
+
 typedef bool _ElementPredicate<E>(E element);
 
 class WhereIterable<E> extends Iterable<E> {
@@ -224,3 +553,82 @@
 
   E get current => _iterator.current;
 }
+
+/**
+ * The always empty [Iterable].
+ */
+class EmptyIterable<E> extends Iterable<E> {
+  const EmptyIterable();
+
+  Iterator<E> get iterator => const EmptyIterator();
+
+  void forEach(void action(E element)) {}
+
+  bool get isEmpty => true;
+
+  int get length => 0;
+
+  E get first { throw new StateError("No elements"); }
+
+  E get last { throw new StateError("No elements"); }
+
+  E get single { throw new StateError("No elements"); }
+
+  E elementAt(int index) { throw new RangeError.value(index); }
+
+  bool contains(E element) => false;
+
+  bool every(bool test(E element)) => true;
+
+  bool any(bool test(E element)) => false;
+
+  E firstMatching(bool test(E element), { E orElse() }) {
+    if (orElse != null) return orElse();
+    throw new StateError("No matching element");
+  }
+
+  E lastMatching(bool test(E element), { E orElse() }) {
+    if (orElse != null) return orElse();
+    throw new StateError("No matching element");
+  }
+
+  E singleMatching(bool test(E element), { E orElse() }) {
+    if (orElse != null) return orElse();
+    throw new StateError("No matching element");
+  }
+
+  E min([int compare(E a, E b)]) => null;
+
+  E max([int compare(E a, E b)]) => null;
+
+  String join([String separator]) => "";
+
+  Iterable<E> where(bool test(E element)) => this;
+
+  Iterable map(f(E element)) => const EmptyIterable();
+
+  Iterable mappedBy(f(E element)) => const EmptyIterable();
+
+  reduce(var initialValue, combine(var previousValue, E element)) {
+    return initialValue;
+  }
+
+  Iterable<E> skip(int count) => this;
+
+  Iterable<E> skipWhile(bool test(E element)) => this;
+
+  Iterable<E> take(int count) => this;
+
+  Iterable<E> takeWhile(bool test(E element)) => this;
+
+  List toList() => <E>[];
+
+  Set toSet() => new Set<E>();
+}
+
+/** The always empty iterator. */
+class EmptyIterator<E> implements Iterator<E> {
+  const EmptyIterator();
+  bool moveNext() => false;
+  E get current => null;
+}
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index 27eb67f..247bdef 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -5,49 +5,108 @@
 part of dart.core;
 
 /**
- * The String class represents character strings. Strings are
- * immutable. A string is represented by a list of 32-bit Unicode
- * scalar character codes accessible through the [charCodeAt] or the
- * [charCodes] method.
+ * The String class represents sequences of characters. Strings are
+ * immutable. A string is represented by a sequence of Unicode UTF-16
+ * code units accessible through the [codeUnitAt] or the
+ * [codeUnits] members. Their string representation is accessible through
+ * the index-operator.
+ *
+ * The characters of a string are encoded in UTF-16. Decoding UTF-16, which
+ * combines surrogate pairs, yields Unicode code points. Following a similar
+ * terminology to Go we use the name "rune" for an integer representing a
+ * Unicode code point. The runes of a string are accessible through the [runes]
+ * getter.
  */
 abstract class String implements Comparable, Pattern {
   /**
    * Allocates a new String for the specified [charCodes].
+   *
+   * The [charCodes] can be UTF-16 code units or runes. If a char-code value is
+   * 16-bit it is copied verbatim. If it is greater than 16 bits it is
+   * decomposed into a surrogate pair.
    */
-  external factory String.fromCharCodes(List<int> charCodes);
+  external factory String.fromCharCodes(Iterable<int> charCodes);
+
+  /**
+   * *Deprecated*. Use [String.fromCharCode] instead.
+   */
+  factory String.character(int charCode) => new String.fromCharCode(charCode);
 
   /**
    * Allocates a new String for the specified [charCode].
    *
-   * The built string is of [length] one, if the [charCode] lies inside the
-   * basic multilingual plane (plane 0). Otherwise the [length] is 2 and
+   * The new string contains a single code unit if the [charCode] can be
+   * represented by a single UTF-16 code unit. Otherwise the [length] is 2 and
    * the code units form a surrogate pair.
+   *
+   * It is allowed (though generally discouraged) to create a String with only
+   * one half of a surrogate pair.
    */
-  factory String.character(int charCode) {
+  factory String.fromCharCode(int charCode) {
     List<int> charCodes = new List<int>.fixedLength(1, fill: charCode);
     return new String.fromCharCodes(charCodes);
   }
 
   /**
    * Gets the character (as [String]) at the given [index].
+   *
+   * The returned string represents exactly one UTF-16 code unit which may be
+   * half of a surrogate pair. For example the Unicode character for a
+   * musical G-clef ("𝄞") with rune value 0x1D11E consists of a UTF-16 surrogate
+   * pair: `"\uDBFF\uDFFD"`. Using the index-operator on this string yields
+   * a String with half of a surrogate pair:
+   *
+   *     var clef = "\uDBFF\uDFFD";
+   *     clef.length;  // => 2
+   *     clef.runes.first == 0x1D11E;  // => true
+   *     clef.runes.length;  // => 1
+   *     // The following strings are halves of a UTF-16 surrogate pair and
+   *     // thus invalid UTF-16 strings:
+   *     clef[0];  // => "\uDBFF"
+   *     clef[1];  // => "\uDFFD"
+   *
+   * This method is equivalent to
+   * `new String.fromCharCode(this.codeUnitAt(index))`.
    */
   String operator [](int index);
 
   /**
    * Gets the scalar character code at the given [index].
+   *
+   * *This method is deprecated. Please use [codeUnitAt] instead.*
    */
   int charCodeAt(int index);
 
   /**
+   * Returns the 16-bit UTF-16 code unit at the given [index].
+   */
+  int codeUnitAt(int index);
+
+  /**
    * The length of the string.
+   *
+   * Returns the number of UTF-16 code units in this string. The number
+   * of [runes] might be less, if the string contains characters outside
+   * the basic multilingual plane (plane 0).
    */
   int get length;
 
   /**
-   * Returns whether the two strings are equal. This method compares
-   * each individual scalar character codes of the strings.
+   * Returns whether the two strings are equal.
+   *
+   * This method compares each individual code unit of the strings. It does not
+   * check for Unicode equivalence. For example the two following strings both
+   * represent the string "Amélie" but, due to their different encoding will
+   * not return equal.
+   *
+   *     "Am\xe9lie"
+   *     "Ame\u{301}lie"
+   *
+   * In the first string the "é" is encoded as a single unicode code unit,
+   * whereas the second string encodes it as "e" with the combining
+   * accent character "◌́".
    */
-  bool operator ==(String other);
+  bool operator ==(var other);
 
   /**
    * Returns whether this string ends with [other].
@@ -152,11 +211,31 @@
   /**
    * Splits the string around matches of [pattern]. Returns
    * a list of substrings.
+   *
+   * Splitting with an empty string pattern (`""`) splits at UTF-16 code unit
+   * boundaries and not at rune boundaries. The following two expressions
+   * are hence equivalent:
+   *
+   *     string.split("")
+   *     string.codeUnits.map((unit) => new String.character(unit))
+   *
+   * Unless it guaranteed that the string is in the basic multilingual plane
+   * (meaning that each code unit represents a rune) it is often better to
+   * map the runes instead:
+   *
+   *     string.runes.map((rune) => new String.character(rune))
    */
   List<String> split(Pattern pattern);
 
   /**
-   * Returns a list of the characters of this string.
+   * Returns a list of the individual code-units converted to strings.
+   *
+   * *Deprecated*
+   * If you want to split on code-unit boundaries, use [split]. If you
+   * want to split on rune boundaries, use [runes] and map the result.
+   *
+   *     Iterable<String> characters =
+   *         string.runes.map((c) => new String.fromCharCode(c));
    */
   List<String> splitChars();
 
@@ -178,19 +257,40 @@
                        String onNonMatch(String nonMatch)});
 
   /**
-   * Returns a list of the scalar character codes of this string.
+   * Returns a list of UTF-16 code units of this string.
+   *
+   * *This getter is deprecated. Use [codeUnits] instead.*
    */
   List<int> get charCodes;
 
   /**
-   * If this string is not already all lower case, returns a new string
-   * where all characters  are made lower case. Returns [:this:] otherwise.
+   * Returns an iterable of the UTF-16 code units of this string.
    */
+  // TODO(floitsch): should it return a list?
+  // TODO(floitsch): make it a bidirectional iterator.
+  Iterable<int> get codeUnits;
+
+  /**
+   * Returns an iterable of Unicode code-points of this string.
+   *
+   * If the string contains surrogate pairs, they will be combined and returned
+   * as one integer by this iterator. Unmatched surrogate halves are treated
+   * like valid 16-bit code-units.
+   */
+  // TODO(floitsch): make it a Runes class.
+  Iterable<int> get runes;
+
+  /**
+   * If this string is not already all lower case, returns a new string
+   * where all characters are made lower case. Returns [:this:] otherwise.
+   */
+  // TODO(floitsch): document better. (See EcmaScript for description).
   String toLowerCase();
 
   /**
-   * If this string is not already all uper case, returns a new string
+   * If this string is not already all upper case, returns a new string
    * where all characters are made upper case. Returns [:this:] otherwise.
    */
+  // TODO(floitsch): document better. (See EcmaScript for description).
   String toUpperCase();
 }
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index d540e7b..6e2a270 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -19,6 +19,7 @@
 // DO NOT EDIT
 // Auto-generated dart:html library.
 
+/// The Dart HTML library.
 
 // Not actually used, but imported since dart:html can generate these objects.
 
@@ -26,8 +27,14 @@
 
 
 
+/**
+ * The top-level Window object.
+ */
 Window get window => JS('Window', 'window');
 
+/**
+ * The top-level Document object.
+ */
 HtmlDocument get document => JS('Document', 'document');
 
 Element query(String selector) => document.query(selector);
@@ -61,7 +68,7 @@
 @DomName('AbstractWorker')
 class AbstractWorker extends EventTarget native "*AbstractWorker" {
 
-  @DomName('AbstractWorker.error')
+  @DomName('AbstractWorker.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
@@ -85,7 +92,7 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
 
-  @DomName('AbstractWorker.error')
+  @DomName('AbstractWorker.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 }
@@ -215,35 +222,35 @@
 @SupportedBrowser(SupportedBrowser.SAFARI)
 class ApplicationCache extends EventTarget native "*DOMApplicationCache" {
 
-  @DomName('DOMApplicationCache.cached')
+  @DomName('DOMApplicationCache.cachedEvent')
   @DocsEditable
   static const EventStreamProvider<Event> cachedEvent = const EventStreamProvider<Event>('cached');
 
-  @DomName('DOMApplicationCache.checking')
+  @DomName('DOMApplicationCache.checkingEvent')
   @DocsEditable
   static const EventStreamProvider<Event> checkingEvent = const EventStreamProvider<Event>('checking');
 
-  @DomName('DOMApplicationCache.downloading')
+  @DomName('DOMApplicationCache.downloadingEvent')
   @DocsEditable
   static const EventStreamProvider<Event> downloadingEvent = const EventStreamProvider<Event>('downloading');
 
-  @DomName('DOMApplicationCache.error')
+  @DomName('DOMApplicationCache.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('DOMApplicationCache.noupdate')
+  @DomName('DOMApplicationCache.noupdateEvent')
   @DocsEditable
   static const EventStreamProvider<Event> noUpdateEvent = const EventStreamProvider<Event>('noupdate');
 
-  @DomName('DOMApplicationCache.obsolete')
+  @DomName('DOMApplicationCache.obsoleteEvent')
   @DocsEditable
   static const EventStreamProvider<Event> obsoleteEvent = const EventStreamProvider<Event>('obsolete');
 
-  @DomName('DOMApplicationCache.progress')
+  @DomName('DOMApplicationCache.progressEvent')
   @DocsEditable
   static const EventStreamProvider<Event> progressEvent = const EventStreamProvider<Event>('progress');
 
-  @DomName('DOMApplicationCache.updateready')
+  @DomName('DOMApplicationCache.updatereadyEvent')
   @DocsEditable
   static const EventStreamProvider<Event> updateReadyEvent = const EventStreamProvider<Event>('updateready');
 
@@ -298,35 +305,35 @@
   @DocsEditable
   void update() native;
 
-  @DomName('DOMApplicationCache.cached')
+  @DomName('DOMApplicationCache.oncached')
   @DocsEditable
   Stream<Event> get onCached => cachedEvent.forTarget(this);
 
-  @DomName('DOMApplicationCache.checking')
+  @DomName('DOMApplicationCache.onchecking')
   @DocsEditable
   Stream<Event> get onChecking => checkingEvent.forTarget(this);
 
-  @DomName('DOMApplicationCache.downloading')
+  @DomName('DOMApplicationCache.ondownloading')
   @DocsEditable
   Stream<Event> get onDownloading => downloadingEvent.forTarget(this);
 
-  @DomName('DOMApplicationCache.error')
+  @DomName('DOMApplicationCache.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('DOMApplicationCache.noupdate')
+  @DomName('DOMApplicationCache.onnoupdate')
   @DocsEditable
   Stream<Event> get onNoUpdate => noUpdateEvent.forTarget(this);
 
-  @DomName('DOMApplicationCache.obsolete')
+  @DomName('DOMApplicationCache.onobsolete')
   @DocsEditable
   Stream<Event> get onObsolete => obsoleteEvent.forTarget(this);
 
-  @DomName('DOMApplicationCache.progress')
+  @DomName('DOMApplicationCache.onprogress')
   @DocsEditable
   Stream<Event> get onProgress => progressEvent.forTarget(this);
 
-  @DomName('DOMApplicationCache.updateready')
+  @DomName('DOMApplicationCache.onupdateready')
   @DocsEditable
   Stream<Event> get onUpdateReady => updateReadyEvent.forTarget(this);
 }
@@ -367,6 +374,16 @@
 
 
 @DocsEditable
+/**
+ * DOM Area Element, which links regions of an image map with a hyperlink.
+ *
+ * The element can also define an uninteractive region of the map.
+ *
+ * See also:
+ *
+ * * [<area>](https://developer.mozilla.org/en-US/docs/HTML/Element/area)
+ * on MDN.
+ */
 @DomName('HTMLAreaElement')
 class AreaElement extends Element native "*HTMLAreaElement" {
 
@@ -591,19 +608,19 @@
 @DomName('BatteryManager')
 class BatteryManager extends EventTarget native "*BatteryManager" {
 
-  @DomName('BatteryManager.chargingchange')
+  @DomName('BatteryManager.chargingchangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> chargingChangeEvent = const EventStreamProvider<Event>('chargingchange');
 
-  @DomName('BatteryManager.chargingtimechange')
+  @DomName('BatteryManager.chargingtimechangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> chargingTimeChangeEvent = const EventStreamProvider<Event>('chargingtimechange');
 
-  @DomName('BatteryManager.dischargingtimechange')
+  @DomName('BatteryManager.dischargingtimechangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> dischargingTimeChangeEvent = const EventStreamProvider<Event>('dischargingtimechange');
 
-  @DomName('BatteryManager.levelchange')
+  @DomName('BatteryManager.levelchangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> levelChangeEvent = const EventStreamProvider<Event>('levelchange');
 
@@ -643,19 +660,19 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
 
-  @DomName('BatteryManager.chargingchange')
+  @DomName('BatteryManager.onchargingchange')
   @DocsEditable
   Stream<Event> get onChargingChange => chargingChangeEvent.forTarget(this);
 
-  @DomName('BatteryManager.chargingtimechange')
+  @DomName('BatteryManager.onchargingtimechange')
   @DocsEditable
   Stream<Event> get onChargingTimeChange => chargingTimeChangeEvent.forTarget(this);
 
-  @DomName('BatteryManager.dischargingtimechange')
+  @DomName('BatteryManager.ondischargingtimechange')
   @DocsEditable
   Stream<Event> get onDischargingTimeChange => dischargingTimeChangeEvent.forTarget(this);
 
-  @DomName('BatteryManager.levelchange')
+  @DomName('BatteryManager.onlevelchange')
   @DocsEditable
   Stream<Event> get onLevelChange => levelChangeEvent.forTarget(this);
 }
@@ -740,55 +757,55 @@
 @DomName('HTMLBodyElement')
 class BodyElement extends Element native "*HTMLBodyElement" {
 
-  @DomName('HTMLBodyElement.beforeunload')
+  @DomName('HTMLBodyElement.beforeunloadEvent')
   @DocsEditable
   static const EventStreamProvider<Event> beforeUnloadEvent = const EventStreamProvider<Event>('beforeunload');
 
-  @DomName('HTMLBodyElement.blur')
+  @DomName('HTMLBodyElement.blurEvent')
   @DocsEditable
   static const EventStreamProvider<Event> blurEvent = const EventStreamProvider<Event>('blur');
 
-  @DomName('HTMLBodyElement.error')
+  @DomName('HTMLBodyElement.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('HTMLBodyElement.focus')
+  @DomName('HTMLBodyElement.focusEvent')
   @DocsEditable
   static const EventStreamProvider<Event> focusEvent = const EventStreamProvider<Event>('focus');
 
-  @DomName('HTMLBodyElement.hashchange')
+  @DomName('HTMLBodyElement.hashchangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> hashChangeEvent = const EventStreamProvider<Event>('hashchange');
 
-  @DomName('HTMLBodyElement.load')
+  @DomName('HTMLBodyElement.loadEvent')
   @DocsEditable
   static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');
 
-  @DomName('HTMLBodyElement.message')
+  @DomName('HTMLBodyElement.messageEvent')
   @DocsEditable
   static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
 
-  @DomName('HTMLBodyElement.offline')
+  @DomName('HTMLBodyElement.offlineEvent')
   @DocsEditable
   static const EventStreamProvider<Event> offlineEvent = const EventStreamProvider<Event>('offline');
 
-  @DomName('HTMLBodyElement.online')
+  @DomName('HTMLBodyElement.onlineEvent')
   @DocsEditable
   static const EventStreamProvider<Event> onlineEvent = const EventStreamProvider<Event>('online');
 
-  @DomName('HTMLBodyElement.popstate')
+  @DomName('HTMLBodyElement.popstateEvent')
   @DocsEditable
   static const EventStreamProvider<PopStateEvent> popStateEvent = const EventStreamProvider<PopStateEvent>('popstate');
 
-  @DomName('HTMLBodyElement.resize')
+  @DomName('HTMLBodyElement.resizeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');
 
-  @DomName('HTMLBodyElement.storage')
+  @DomName('HTMLBodyElement.storageEvent')
   @DocsEditable
   static const EventStreamProvider<StorageEvent> storageEvent = const EventStreamProvider<StorageEvent>('storage');
 
-  @DomName('HTMLBodyElement.unload')
+  @DomName('HTMLBodyElement.unloadEvent')
   @DocsEditable
   static const EventStreamProvider<Event> unloadEvent = const EventStreamProvider<Event>('unload');
 
@@ -802,55 +819,55 @@
   BodyElementEvents get on =>
     new BodyElementEvents(this);
 
-  @DomName('HTMLBodyElement.beforeunload')
+  @DomName('HTMLBodyElement.onbeforeunload')
   @DocsEditable
   Stream<Event> get onBeforeUnload => beforeUnloadEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.blur')
+  @DomName('HTMLBodyElement.onblur')
   @DocsEditable
   Stream<Event> get onBlur => blurEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.error')
+  @DomName('HTMLBodyElement.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.focus')
+  @DomName('HTMLBodyElement.onfocus')
   @DocsEditable
   Stream<Event> get onFocus => focusEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.hashchange')
+  @DomName('HTMLBodyElement.onhashchange')
   @DocsEditable
   Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.load')
+  @DomName('HTMLBodyElement.onload')
   @DocsEditable
   Stream<Event> get onLoad => loadEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.message')
+  @DomName('HTMLBodyElement.onmessage')
   @DocsEditable
   Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.offline')
+  @DomName('HTMLBodyElement.onoffline')
   @DocsEditable
   Stream<Event> get onOffline => offlineEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.online')
+  @DomName('HTMLBodyElement.ononline')
   @DocsEditable
   Stream<Event> get onOnline => onlineEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.popstate')
+  @DomName('HTMLBodyElement.onpopstate')
   @DocsEditable
   Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.resize')
+  @DomName('HTMLBodyElement.onresize')
   @DocsEditable
   Stream<Event> get onResize => resizeEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.storage')
+  @DomName('HTMLBodyElement.onstorage')
   @DocsEditable
   Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.unload')
+  @DomName('HTMLBodyElement.onunload')
   @DocsEditable
   Stream<Event> get onUnload => unloadEvent.forTarget(this);
 }
@@ -1761,8 +1778,8 @@
       JS('void', 'console.time(#)', title) : null;
 
   @DomName('Console.timeEnd')
-  void timeEnd(String title, Object arg) => _isConsoleDefined ?
-      JS('void', 'console.timeEnd(#, #)', title, arg) : null;
+  void timeEnd(String timerName) => _isConsoleDefined ?
+      JS('void', 'console.timeEnd(#)', timerName) : null;
 
   @DomName('Console.timeStamp')
   void timeStamp(Object arg) => _isConsoleDefined ?
@@ -6062,7 +6079,7 @@
 @DomName('DedicatedWorkerContext')
 class DedicatedWorkerContext extends WorkerContext native "*DedicatedWorkerContext" {
 
-  @DomName('DedicatedWorkerContext.message')
+  @DomName('DedicatedWorkerContext.messageEvent')
   @DocsEditable
   static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
 
@@ -6091,7 +6108,7 @@
   @DocsEditable
   void _postMessage_2(message) native;
 
-  @DomName('DedicatedWorkerContext.message')
+  @DomName('DedicatedWorkerContext.onmessage')
   @DocsEditable
   Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
 }
@@ -6386,19 +6403,19 @@
 {
 
 
-  @DomName('Document.readystatechange')
+  @DomName('Document.readystatechangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> readyStateChangeEvent = const EventStreamProvider<Event>('readystatechange');
 
-  @DomName('Document.selectionchange')
+  @DomName('Document.selectionchangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> selectionChangeEvent = const EventStreamProvider<Event>('selectionchange');
 
-  @DomName('Document.webkitpointerlockchange')
+  @DomName('Document.webkitpointerlockchangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> pointerLockChangeEvent = const EventStreamProvider<Event>('webkitpointerlockchange');
 
-  @DomName('Document.webkitpointerlockerror')
+  @DomName('Document.webkitpointerlockerrorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> pointerLockErrorEvent = const EventStreamProvider<Event>('webkitpointerlockerror');
 
@@ -6673,199 +6690,199 @@
   @DocsEditable
   void $dom_webkitExitPointerLock() native;
 
-  @DomName('Document.abort')
+  @DomName('Document.onabort')
   @DocsEditable
   Stream<Event> get onAbort => Element.abortEvent.forTarget(this);
 
-  @DomName('Document.beforecopy')
+  @DomName('Document.onbeforecopy')
   @DocsEditable
   Stream<Event> get onBeforeCopy => Element.beforeCopyEvent.forTarget(this);
 
-  @DomName('Document.beforecut')
+  @DomName('Document.onbeforecut')
   @DocsEditable
   Stream<Event> get onBeforeCut => Element.beforeCutEvent.forTarget(this);
 
-  @DomName('Document.beforepaste')
+  @DomName('Document.onbeforepaste')
   @DocsEditable
   Stream<Event> get onBeforePaste => Element.beforePasteEvent.forTarget(this);
 
-  @DomName('Document.blur')
+  @DomName('Document.onblur')
   @DocsEditable
   Stream<Event> get onBlur => Element.blurEvent.forTarget(this);
 
-  @DomName('Document.change')
+  @DomName('Document.onchange')
   @DocsEditable
   Stream<Event> get onChange => Element.changeEvent.forTarget(this);
 
-  @DomName('Document.click')
+  @DomName('Document.onclick')
   @DocsEditable
   Stream<MouseEvent> get onClick => Element.clickEvent.forTarget(this);
 
-  @DomName('Document.contextmenu')
+  @DomName('Document.oncontextmenu')
   @DocsEditable
   Stream<MouseEvent> get onContextMenu => Element.contextMenuEvent.forTarget(this);
 
-  @DomName('Document.copy')
+  @DomName('Document.oncopy')
   @DocsEditable
   Stream<Event> get onCopy => Element.copyEvent.forTarget(this);
 
-  @DomName('Document.cut')
+  @DomName('Document.oncut')
   @DocsEditable
   Stream<Event> get onCut => Element.cutEvent.forTarget(this);
 
-  @DomName('Document.dblclick')
+  @DomName('Document.ondblclick')
   @DocsEditable
   Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);
 
-  @DomName('Document.drag')
+  @DomName('Document.ondrag')
   @DocsEditable
   Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);
 
-  @DomName('Document.dragend')
+  @DomName('Document.ondragend')
   @DocsEditable
   Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);
 
-  @DomName('Document.dragenter')
+  @DomName('Document.ondragenter')
   @DocsEditable
   Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);
 
-  @DomName('Document.dragleave')
+  @DomName('Document.ondragleave')
   @DocsEditable
   Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);
 
-  @DomName('Document.dragover')
+  @DomName('Document.ondragover')
   @DocsEditable
   Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);
 
-  @DomName('Document.dragstart')
+  @DomName('Document.ondragstart')
   @DocsEditable
   Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);
 
-  @DomName('Document.drop')
+  @DomName('Document.ondrop')
   @DocsEditable
   Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);
 
-  @DomName('Document.error')
+  @DomName('Document.onerror')
   @DocsEditable
   Stream<Event> get onError => Element.errorEvent.forTarget(this);
 
-  @DomName('Document.focus')
+  @DomName('Document.onfocus')
   @DocsEditable
   Stream<Event> get onFocus => Element.focusEvent.forTarget(this);
 
-  @DomName('Document.input')
+  @DomName('Document.oninput')
   @DocsEditable
   Stream<Event> get onInput => Element.inputEvent.forTarget(this);
 
-  @DomName('Document.invalid')
+  @DomName('Document.oninvalid')
   @DocsEditable
   Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);
 
-  @DomName('Document.keydown')
+  @DomName('Document.onkeydown')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);
 
-  @DomName('Document.keypress')
+  @DomName('Document.onkeypress')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);
 
-  @DomName('Document.keyup')
+  @DomName('Document.onkeyup')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);
 
-  @DomName('Document.load')
+  @DomName('Document.onload')
   @DocsEditable
   Stream<Event> get onLoad => Element.loadEvent.forTarget(this);
 
-  @DomName('Document.mousedown')
+  @DomName('Document.onmousedown')
   @DocsEditable
   Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);
 
-  @DomName('Document.mousemove')
+  @DomName('Document.onmousemove')
   @DocsEditable
   Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);
 
-  @DomName('Document.mouseout')
+  @DomName('Document.onmouseout')
   @DocsEditable
   Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);
 
-  @DomName('Document.mouseover')
+  @DomName('Document.onmouseover')
   @DocsEditable
   Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);
 
-  @DomName('Document.mouseup')
+  @DomName('Document.onmouseup')
   @DocsEditable
   Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);
 
-  @DomName('Document.mousewheel')
+  @DomName('Document.onmousewheel')
   @DocsEditable
   Stream<WheelEvent> get onMouseWheel => Element.mouseWheelEvent.forTarget(this);
 
-  @DomName('Document.paste')
+  @DomName('Document.onpaste')
   @DocsEditable
   Stream<Event> get onPaste => Element.pasteEvent.forTarget(this);
 
-  @DomName('Document.readystatechange')
+  @DomName('Document.onreadystatechange')
   @DocsEditable
   Stream<Event> get onReadyStateChange => readyStateChangeEvent.forTarget(this);
 
-  @DomName('Document.reset')
+  @DomName('Document.onreset')
   @DocsEditable
   Stream<Event> get onReset => Element.resetEvent.forTarget(this);
 
-  @DomName('Document.scroll')
+  @DomName('Document.onscroll')
   @DocsEditable
   Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);
 
-  @DomName('Document.search')
+  @DomName('Document.onsearch')
   @DocsEditable
   Stream<Event> get onSearch => Element.searchEvent.forTarget(this);
 
-  @DomName('Document.select')
+  @DomName('Document.onselect')
   @DocsEditable
   Stream<Event> get onSelect => Element.selectEvent.forTarget(this);
 
-  @DomName('Document.selectionchange')
+  @DomName('Document.onselectionchange')
   @DocsEditable
   Stream<Event> get onSelectionChange => selectionChangeEvent.forTarget(this);
 
-  @DomName('Document.selectstart')
+  @DomName('Document.onselectstart')
   @DocsEditable
   Stream<Event> get onSelectStart => Element.selectStartEvent.forTarget(this);
 
-  @DomName('Document.submit')
+  @DomName('Document.onsubmit')
   @DocsEditable
   Stream<Event> get onSubmit => Element.submitEvent.forTarget(this);
 
-  @DomName('Document.touchcancel')
+  @DomName('Document.ontouchcancel')
   @DocsEditable
   Stream<TouchEvent> get onTouchCancel => Element.touchCancelEvent.forTarget(this);
 
-  @DomName('Document.touchend')
+  @DomName('Document.ontouchend')
   @DocsEditable
   Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);
 
-  @DomName('Document.touchmove')
+  @DomName('Document.ontouchmove')
   @DocsEditable
   Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);
 
-  @DomName('Document.touchstart')
+  @DomName('Document.ontouchstart')
   @DocsEditable
   Stream<TouchEvent> get onTouchStart => Element.touchStartEvent.forTarget(this);
 
-  @DomName('Document.webkitfullscreenchange')
+  @DomName('Document.onwebkitfullscreenchange')
   @DocsEditable
   Stream<Event> get onFullscreenChange => Element.fullscreenChangeEvent.forTarget(this);
 
-  @DomName('Document.webkitfullscreenerror')
+  @DomName('Document.onwebkitfullscreenerror')
   @DocsEditable
   Stream<Event> get onFullscreenError => Element.fullscreenErrorEvent.forTarget(this);
 
-  @DomName('Document.webkitpointerlockchange')
+  @DomName('Document.onwebkitpointerlockchange')
   @DocsEditable
   Stream<Event> get onPointerLockChange => pointerLockChangeEvent.forTarget(this);
 
-  @DomName('Document.webkitpointerlockerror')
+  @DomName('Document.onwebkitpointerlockerror')
   @DocsEditable
   Stream<Event> get onPointerLockError => pointerLockErrorEvent.forTarget(this);
 
@@ -6965,15 +6982,6 @@
   factory DocumentFragment.svg(String svgContent) =>
       _DocumentFragmentFactoryProvider.createDocumentFragment_svg(svgContent);
 
-  @deprecated
-  List<Element> get elements => this.children;
-
-  // TODO: The type of value should be Collection<Element>. See http://b/5392897
-  @deprecated
-  void set elements(value) {
-    this.children = value;
-  }
-
   // Native field is used only by Dart code so does not lead to instantiation
   // of native classes
   @Creates('Null')
@@ -7018,14 +7026,27 @@
     this.nodes.addAll(nodes);
   }
 
+  /**
+   * Adds the specified element after the last child of this
+   * document fragment.
+   */
   void append(Element element) {
     this.children.add(element);
   }
 
+  /**
+   * Adds the specified text as a text node after the last child of this
+   * document fragment.
+   */
   void appendText(String text) {
     this.nodes.add(new Text(text));
   }
 
+
+  /**
+   * Parses the specified text as HTML and adds the resulting node after the
+   * last child of this document fragment.
+   */
   void appendHtml(String text) {
     this.nodes.add(new DocumentFragment.html(text));
   }
@@ -7220,7 +7241,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(DomMimeType element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(DomMimeType element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -7474,7 +7495,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(DomPlugin element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(DomPlugin element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -7835,7 +7856,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(String element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(String element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -8094,7 +8115,7 @@
   }
 
   Iterable map(f(Element element)) {
-    return IterableMixinWorkaround.map(this, f);
+    return IterableMixinWorkaround.mapList(this, f);
   }
 
   List mappedBy(f(Element element)) {
@@ -8311,7 +8332,7 @@
   }
 
   Iterable map(f(Element element)) {
-    return IterableMixinWorkaround.map(this, f);
+    return IterableMixinWorkaround.mapList(this, f);
   }
 
   List mappedBy(f(Element element)) {
@@ -8608,27 +8629,6 @@
   }
 
   /**
-   * Deprecated, use innerHtml instead.
-   */
-  @deprecated
-  String get innerHTML => this.innerHtml;
-  @deprecated
-  void set innerHTML(String value) {
-    this.innerHtml = value;
-  }
-
-  @deprecated
-  void set elements(Collection<Element> value) {
-    this.children = value;
-  }
-
-  /**
-   * Deprecated, use [children] instead.
-   */
-  @deprecated
-  List<Element> get elements => this.children;
-
-  /**
    * List of the direct children of this element.
    *
    * This collection can be used to add and remove elements from the document.
@@ -8944,191 +8944,191 @@
   }
 
 
-  @DomName('Element.abort')
+  @DomName('Element.abortEvent')
   @DocsEditable
   static const EventStreamProvider<Event> abortEvent = const EventStreamProvider<Event>('abort');
 
-  @DomName('Element.beforecopy')
+  @DomName('Element.beforecopyEvent')
   @DocsEditable
   static const EventStreamProvider<Event> beforeCopyEvent = const EventStreamProvider<Event>('beforecopy');
 
-  @DomName('Element.beforecut')
+  @DomName('Element.beforecutEvent')
   @DocsEditable
   static const EventStreamProvider<Event> beforeCutEvent = const EventStreamProvider<Event>('beforecut');
 
-  @DomName('Element.beforepaste')
+  @DomName('Element.beforepasteEvent')
   @DocsEditable
   static const EventStreamProvider<Event> beforePasteEvent = const EventStreamProvider<Event>('beforepaste');
 
-  @DomName('Element.blur')
+  @DomName('Element.blurEvent')
   @DocsEditable
   static const EventStreamProvider<Event> blurEvent = const EventStreamProvider<Event>('blur');
 
-  @DomName('Element.change')
+  @DomName('Element.changeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');
 
-  @DomName('Element.click')
+  @DomName('Element.clickEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> clickEvent = const EventStreamProvider<MouseEvent>('click');
 
-  @DomName('Element.contextmenu')
+  @DomName('Element.contextmenuEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> contextMenuEvent = const EventStreamProvider<MouseEvent>('contextmenu');
 
-  @DomName('Element.copy')
+  @DomName('Element.copyEvent')
   @DocsEditable
   static const EventStreamProvider<Event> copyEvent = const EventStreamProvider<Event>('copy');
 
-  @DomName('Element.cut')
+  @DomName('Element.cutEvent')
   @DocsEditable
   static const EventStreamProvider<Event> cutEvent = const EventStreamProvider<Event>('cut');
 
-  @DomName('Element.dblclick')
+  @DomName('Element.dblclickEvent')
   @DocsEditable
   static const EventStreamProvider<Event> doubleClickEvent = const EventStreamProvider<Event>('dblclick');
 
-  @DomName('Element.drag')
+  @DomName('Element.dragEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragEvent = const EventStreamProvider<MouseEvent>('drag');
 
-  @DomName('Element.dragend')
+  @DomName('Element.dragendEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragEndEvent = const EventStreamProvider<MouseEvent>('dragend');
 
-  @DomName('Element.dragenter')
+  @DomName('Element.dragenterEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragEnterEvent = const EventStreamProvider<MouseEvent>('dragenter');
 
-  @DomName('Element.dragleave')
+  @DomName('Element.dragleaveEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragLeaveEvent = const EventStreamProvider<MouseEvent>('dragleave');
 
-  @DomName('Element.dragover')
+  @DomName('Element.dragoverEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragOverEvent = const EventStreamProvider<MouseEvent>('dragover');
 
-  @DomName('Element.dragstart')
+  @DomName('Element.dragstartEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragStartEvent = const EventStreamProvider<MouseEvent>('dragstart');
 
-  @DomName('Element.drop')
+  @DomName('Element.dropEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dropEvent = const EventStreamProvider<MouseEvent>('drop');
 
-  @DomName('Element.error')
+  @DomName('Element.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('Element.focus')
+  @DomName('Element.focusEvent')
   @DocsEditable
   static const EventStreamProvider<Event> focusEvent = const EventStreamProvider<Event>('focus');
 
-  @DomName('Element.input')
+  @DomName('Element.inputEvent')
   @DocsEditable
   static const EventStreamProvider<Event> inputEvent = const EventStreamProvider<Event>('input');
 
-  @DomName('Element.invalid')
+  @DomName('Element.invalidEvent')
   @DocsEditable
   static const EventStreamProvider<Event> invalidEvent = const EventStreamProvider<Event>('invalid');
 
-  @DomName('Element.keydown')
+  @DomName('Element.keydownEvent')
   @DocsEditable
   static const EventStreamProvider<KeyboardEvent> keyDownEvent = const EventStreamProvider<KeyboardEvent>('keydown');
 
-  @DomName('Element.keypress')
+  @DomName('Element.keypressEvent')
   @DocsEditable
   static const EventStreamProvider<KeyboardEvent> keyPressEvent = const EventStreamProvider<KeyboardEvent>('keypress');
 
-  @DomName('Element.keyup')
+  @DomName('Element.keyupEvent')
   @DocsEditable
   static const EventStreamProvider<KeyboardEvent> keyUpEvent = const EventStreamProvider<KeyboardEvent>('keyup');
 
-  @DomName('Element.load')
+  @DomName('Element.loadEvent')
   @DocsEditable
   static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');
 
-  @DomName('Element.mousedown')
+  @DomName('Element.mousedownEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> mouseDownEvent = const EventStreamProvider<MouseEvent>('mousedown');
 
-  @DomName('Element.mousemove')
+  @DomName('Element.mousemoveEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> mouseMoveEvent = const EventStreamProvider<MouseEvent>('mousemove');
 
-  @DomName('Element.mouseout')
+  @DomName('Element.mouseoutEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> mouseOutEvent = const EventStreamProvider<MouseEvent>('mouseout');
 
-  @DomName('Element.mouseover')
+  @DomName('Element.mouseoverEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> mouseOverEvent = const EventStreamProvider<MouseEvent>('mouseover');
 
-  @DomName('Element.mouseup')
+  @DomName('Element.mouseupEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> mouseUpEvent = const EventStreamProvider<MouseEvent>('mouseup');
 
-  @DomName('Element.paste')
+  @DomName('Element.pasteEvent')
   @DocsEditable
   static const EventStreamProvider<Event> pasteEvent = const EventStreamProvider<Event>('paste');
 
-  @DomName('Element.reset')
+  @DomName('Element.resetEvent')
   @DocsEditable
   static const EventStreamProvider<Event> resetEvent = const EventStreamProvider<Event>('reset');
 
-  @DomName('Element.scroll')
+  @DomName('Element.scrollEvent')
   @DocsEditable
   static const EventStreamProvider<Event> scrollEvent = const EventStreamProvider<Event>('scroll');
 
-  @DomName('Element.search')
+  @DomName('Element.searchEvent')
   @DocsEditable
   static const EventStreamProvider<Event> searchEvent = const EventStreamProvider<Event>('search');
 
-  @DomName('Element.select')
+  @DomName('Element.selectEvent')
   @DocsEditable
   static const EventStreamProvider<Event> selectEvent = const EventStreamProvider<Event>('select');
 
-  @DomName('Element.selectstart')
+  @DomName('Element.selectstartEvent')
   @DocsEditable
   static const EventStreamProvider<Event> selectStartEvent = const EventStreamProvider<Event>('selectstart');
 
-  @DomName('Element.submit')
+  @DomName('Element.submitEvent')
   @DocsEditable
   static const EventStreamProvider<Event> submitEvent = const EventStreamProvider<Event>('submit');
 
-  @DomName('Element.touchcancel')
+  @DomName('Element.touchcancelEvent')
   @DocsEditable
   static const EventStreamProvider<TouchEvent> touchCancelEvent = const EventStreamProvider<TouchEvent>('touchcancel');
 
-  @DomName('Element.touchend')
+  @DomName('Element.touchendEvent')
   @DocsEditable
   static const EventStreamProvider<TouchEvent> touchEndEvent = const EventStreamProvider<TouchEvent>('touchend');
 
-  @DomName('Element.touchenter')
+  @DomName('Element.touchenterEvent')
   @DocsEditable
   static const EventStreamProvider<TouchEvent> touchEnterEvent = const EventStreamProvider<TouchEvent>('touchenter');
 
-  @DomName('Element.touchleave')
+  @DomName('Element.touchleaveEvent')
   @DocsEditable
   static const EventStreamProvider<TouchEvent> touchLeaveEvent = const EventStreamProvider<TouchEvent>('touchleave');
 
-  @DomName('Element.touchmove')
+  @DomName('Element.touchmoveEvent')
   @DocsEditable
   static const EventStreamProvider<TouchEvent> touchMoveEvent = const EventStreamProvider<TouchEvent>('touchmove');
 
-  @DomName('Element.touchstart')
+  @DomName('Element.touchstartEvent')
   @DocsEditable
   static const EventStreamProvider<TouchEvent> touchStartEvent = const EventStreamProvider<TouchEvent>('touchstart');
 
-  @DomName('Element.webkitTransitionEnd')
+  @DomName('Element.webkitTransitionEndEvent')
   @DocsEditable
   static const EventStreamProvider<TransitionEvent> transitionEndEvent = const EventStreamProvider<TransitionEvent>('webkitTransitionEnd');
 
-  @DomName('Element.webkitfullscreenchange')
+  @DomName('Element.webkitfullscreenchangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> fullscreenChangeEvent = const EventStreamProvider<Event>('webkitfullscreenchange');
 
-  @DomName('Element.webkitfullscreenerror')
+  @DomName('Element.webkitfullscreenerrorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> fullscreenErrorEvent = const EventStreamProvider<Event>('webkitfullscreenerror');
 
@@ -9423,195 +9423,195 @@
   @DocsEditable
   void webkitRequestPointerLock() native;
 
-  @DomName('Element.abort')
+  @DomName('Element.onabort')
   @DocsEditable
   Stream<Event> get onAbort => abortEvent.forTarget(this);
 
-  @DomName('Element.beforecopy')
+  @DomName('Element.onbeforecopy')
   @DocsEditable
   Stream<Event> get onBeforeCopy => beforeCopyEvent.forTarget(this);
 
-  @DomName('Element.beforecut')
+  @DomName('Element.onbeforecut')
   @DocsEditable
   Stream<Event> get onBeforeCut => beforeCutEvent.forTarget(this);
 
-  @DomName('Element.beforepaste')
+  @DomName('Element.onbeforepaste')
   @DocsEditable
   Stream<Event> get onBeforePaste => beforePasteEvent.forTarget(this);
 
-  @DomName('Element.blur')
+  @DomName('Element.onblur')
   @DocsEditable
   Stream<Event> get onBlur => blurEvent.forTarget(this);
 
-  @DomName('Element.change')
+  @DomName('Element.onchange')
   @DocsEditable
   Stream<Event> get onChange => changeEvent.forTarget(this);
 
-  @DomName('Element.click')
+  @DomName('Element.onclick')
   @DocsEditable
   Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
 
-  @DomName('Element.contextmenu')
+  @DomName('Element.oncontextmenu')
   @DocsEditable
   Stream<MouseEvent> get onContextMenu => contextMenuEvent.forTarget(this);
 
-  @DomName('Element.copy')
+  @DomName('Element.oncopy')
   @DocsEditable
   Stream<Event> get onCopy => copyEvent.forTarget(this);
 
-  @DomName('Element.cut')
+  @DomName('Element.oncut')
   @DocsEditable
   Stream<Event> get onCut => cutEvent.forTarget(this);
 
-  @DomName('Element.dblclick')
+  @DomName('Element.ondblclick')
   @DocsEditable
   Stream<Event> get onDoubleClick => doubleClickEvent.forTarget(this);
 
-  @DomName('Element.drag')
+  @DomName('Element.ondrag')
   @DocsEditable
   Stream<MouseEvent> get onDrag => dragEvent.forTarget(this);
 
-  @DomName('Element.dragend')
+  @DomName('Element.ondragend')
   @DocsEditable
   Stream<MouseEvent> get onDragEnd => dragEndEvent.forTarget(this);
 
-  @DomName('Element.dragenter')
+  @DomName('Element.ondragenter')
   @DocsEditable
   Stream<MouseEvent> get onDragEnter => dragEnterEvent.forTarget(this);
 
-  @DomName('Element.dragleave')
+  @DomName('Element.ondragleave')
   @DocsEditable
   Stream<MouseEvent> get onDragLeave => dragLeaveEvent.forTarget(this);
 
-  @DomName('Element.dragover')
+  @DomName('Element.ondragover')
   @DocsEditable
   Stream<MouseEvent> get onDragOver => dragOverEvent.forTarget(this);
 
-  @DomName('Element.dragstart')
+  @DomName('Element.ondragstart')
   @DocsEditable
   Stream<MouseEvent> get onDragStart => dragStartEvent.forTarget(this);
 
-  @DomName('Element.drop')
+  @DomName('Element.ondrop')
   @DocsEditable
   Stream<MouseEvent> get onDrop => dropEvent.forTarget(this);
 
-  @DomName('Element.error')
+  @DomName('Element.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('Element.focus')
+  @DomName('Element.onfocus')
   @DocsEditable
   Stream<Event> get onFocus => focusEvent.forTarget(this);
 
-  @DomName('Element.input')
+  @DomName('Element.oninput')
   @DocsEditable
   Stream<Event> get onInput => inputEvent.forTarget(this);
 
-  @DomName('Element.invalid')
+  @DomName('Element.oninvalid')
   @DocsEditable
   Stream<Event> get onInvalid => invalidEvent.forTarget(this);
 
-  @DomName('Element.keydown')
+  @DomName('Element.onkeydown')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyDown => keyDownEvent.forTarget(this);
 
-  @DomName('Element.keypress')
+  @DomName('Element.onkeypress')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyPress => keyPressEvent.forTarget(this);
 
-  @DomName('Element.keyup')
+  @DomName('Element.onkeyup')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyUp => keyUpEvent.forTarget(this);
 
-  @DomName('Element.load')
+  @DomName('Element.onload')
   @DocsEditable
   Stream<Event> get onLoad => loadEvent.forTarget(this);
 
-  @DomName('Element.mousedown')
+  @DomName('Element.onmousedown')
   @DocsEditable
   Stream<MouseEvent> get onMouseDown => mouseDownEvent.forTarget(this);
 
-  @DomName('Element.mousemove')
+  @DomName('Element.onmousemove')
   @DocsEditable
   Stream<MouseEvent> get onMouseMove => mouseMoveEvent.forTarget(this);
 
-  @DomName('Element.mouseout')
+  @DomName('Element.onmouseout')
   @DocsEditable
   Stream<MouseEvent> get onMouseOut => mouseOutEvent.forTarget(this);
 
-  @DomName('Element.mouseover')
+  @DomName('Element.onmouseover')
   @DocsEditable
   Stream<MouseEvent> get onMouseOver => mouseOverEvent.forTarget(this);
 
-  @DomName('Element.mouseup')
+  @DomName('Element.onmouseup')
   @DocsEditable
   Stream<MouseEvent> get onMouseUp => mouseUpEvent.forTarget(this);
 
-  @DomName('Element.mousewheel')
+  @DomName('Element.onmousewheel')
   @DocsEditable
   Stream<WheelEvent> get onMouseWheel => mouseWheelEvent.forTarget(this);
 
-  @DomName('Element.paste')
+  @DomName('Element.onpaste')
   @DocsEditable
   Stream<Event> get onPaste => pasteEvent.forTarget(this);
 
-  @DomName('Element.reset')
+  @DomName('Element.onreset')
   @DocsEditable
   Stream<Event> get onReset => resetEvent.forTarget(this);
 
-  @DomName('Element.scroll')
+  @DomName('Element.onscroll')
   @DocsEditable
   Stream<Event> get onScroll => scrollEvent.forTarget(this);
 
-  @DomName('Element.search')
+  @DomName('Element.onsearch')
   @DocsEditable
   Stream<Event> get onSearch => searchEvent.forTarget(this);
 
-  @DomName('Element.select')
+  @DomName('Element.onselect')
   @DocsEditable
   Stream<Event> get onSelect => selectEvent.forTarget(this);
 
-  @DomName('Element.selectstart')
+  @DomName('Element.onselectstart')
   @DocsEditable
   Stream<Event> get onSelectStart => selectStartEvent.forTarget(this);
 
-  @DomName('Element.submit')
+  @DomName('Element.onsubmit')
   @DocsEditable
   Stream<Event> get onSubmit => submitEvent.forTarget(this);
 
-  @DomName('Element.touchcancel')
+  @DomName('Element.ontouchcancel')
   @DocsEditable
   Stream<TouchEvent> get onTouchCancel => touchCancelEvent.forTarget(this);
 
-  @DomName('Element.touchend')
+  @DomName('Element.ontouchend')
   @DocsEditable
   Stream<TouchEvent> get onTouchEnd => touchEndEvent.forTarget(this);
 
-  @DomName('Element.touchenter')
+  @DomName('Element.ontouchenter')
   @DocsEditable
   Stream<TouchEvent> get onTouchEnter => touchEnterEvent.forTarget(this);
 
-  @DomName('Element.touchleave')
+  @DomName('Element.ontouchleave')
   @DocsEditable
   Stream<TouchEvent> get onTouchLeave => touchLeaveEvent.forTarget(this);
 
-  @DomName('Element.touchmove')
+  @DomName('Element.ontouchmove')
   @DocsEditable
   Stream<TouchEvent> get onTouchMove => touchMoveEvent.forTarget(this);
 
-  @DomName('Element.touchstart')
+  @DomName('Element.ontouchstart')
   @DocsEditable
   Stream<TouchEvent> get onTouchStart => touchStartEvent.forTarget(this);
 
-  @DomName('Element.webkitTransitionEnd')
+  @DomName('Element.onwebkitTransitionEnd')
   @DocsEditable
   Stream<TransitionEvent> get onTransitionEnd => transitionEndEvent.forTarget(this);
 
-  @DomName('Element.webkitfullscreenchange')
+  @DomName('Element.onwebkitfullscreenchange')
   @DocsEditable
   Stream<Event> get onFullscreenChange => fullscreenChangeEvent.forTarget(this);
 
-  @DomName('Element.webkitfullscreenerror')
+  @DomName('Element.onwebkitfullscreenerror')
   @DocsEditable
   Stream<Event> get onFullscreenError => fullscreenErrorEvent.forTarget(this);
 
@@ -9747,7 +9747,8 @@
   // Optimization to improve performance until the dart2js compiler inlines this
   // method.
   static dynamic createElement_tag(String tag) =>
-      JS('Element', 'document.createElement(#)', tag);
+      // Firefox may return a JS function for some types (Embed, Object).
+      JS('Element|=Object', 'document.createElement(#)', tag);
 }
 // 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
@@ -10331,15 +10332,15 @@
 @DomName('EventSource')
 class EventSource extends EventTarget native "*EventSource" {
 
-  @DomName('EventSource.error')
+  @DomName('EventSource.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('EventSource.message')
+  @DomName('EventSource.messageEvent')
   @DocsEditable
   static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
 
-  @DomName('EventSource.open')
+  @DomName('EventSource.openEvent')
   @DocsEditable
   static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');
 
@@ -10396,15 +10397,15 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
 
-  @DomName('EventSource.error')
+  @DomName('EventSource.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('EventSource.message')
+  @DomName('EventSource.onmessage')
   @DocsEditable
   Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
 
-  @DomName('EventSource.open')
+  @DomName('EventSource.onopen')
   @DocsEditable
   Stream<Event> get onOpen => openEvent.forTarget(this);
 }
@@ -10776,7 +10777,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(File element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(File element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -10940,27 +10941,27 @@
 @DomName('FileReader')
 class FileReader extends EventTarget native "*FileReader" {
 
-  @DomName('FileReader.abort')
+  @DomName('FileReader.abortEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> abortEvent = const EventStreamProvider<ProgressEvent>('abort');
 
-  @DomName('FileReader.error')
+  @DomName('FileReader.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('FileReader.load')
+  @DomName('FileReader.loadEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> loadEvent = const EventStreamProvider<ProgressEvent>('load');
 
-  @DomName('FileReader.loadend')
+  @DomName('FileReader.loadendEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> loadEndEvent = const EventStreamProvider<ProgressEvent>('loadend');
 
-  @DomName('FileReader.loadstart')
+  @DomName('FileReader.loadstartEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> loadStartEvent = const EventStreamProvider<ProgressEvent>('loadstart');
 
-  @DomName('FileReader.progress')
+  @DomName('FileReader.progressEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> progressEvent = const EventStreamProvider<ProgressEvent>('progress');
 
@@ -11031,27 +11032,27 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
 
-  @DomName('FileReader.abort')
+  @DomName('FileReader.onabort')
   @DocsEditable
   Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);
 
-  @DomName('FileReader.error')
+  @DomName('FileReader.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('FileReader.load')
+  @DomName('FileReader.onload')
   @DocsEditable
   Stream<ProgressEvent> get onLoad => loadEvent.forTarget(this);
 
-  @DomName('FileReader.loadend')
+  @DomName('FileReader.onloadend')
   @DocsEditable
   Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);
 
-  @DomName('FileReader.loadstart')
+  @DomName('FileReader.onloadstart')
   @DocsEditable
   Stream<ProgressEvent> get onLoadStart => loadStartEvent.forTarget(this);
 
-  @DomName('FileReader.progress')
+  @DomName('FileReader.onprogress')
   @DocsEditable
   Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);
 }
@@ -11167,27 +11168,27 @@
 @DomName('FileWriter')
 class FileWriter extends EventTarget native "*FileWriter" {
 
-  @DomName('FileWriter.abort')
+  @DomName('FileWriter.abortEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> abortEvent = const EventStreamProvider<ProgressEvent>('abort');
 
-  @DomName('FileWriter.error')
+  @DomName('FileWriter.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('FileWriter.progress')
+  @DomName('FileWriter.progressEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> progressEvent = const EventStreamProvider<ProgressEvent>('progress');
 
-  @DomName('FileWriter.write')
+  @DomName('FileWriter.writeEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> writeEvent = const EventStreamProvider<ProgressEvent>('write');
 
-  @DomName('FileWriter.writeend')
+  @DomName('FileWriter.writeendEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> writeEndEvent = const EventStreamProvider<ProgressEvent>('writeend');
 
-  @DomName('FileWriter.writestart')
+  @DomName('FileWriter.writestartEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> writeStartEvent = const EventStreamProvider<ProgressEvent>('writestart');
 
@@ -11249,27 +11250,27 @@
   @DocsEditable
   void write(Blob data) native;
 
-  @DomName('FileWriter.abort')
+  @DomName('FileWriter.onabort')
   @DocsEditable
   Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);
 
-  @DomName('FileWriter.error')
+  @DomName('FileWriter.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('FileWriter.progress')
+  @DomName('FileWriter.onprogress')
   @DocsEditable
   Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);
 
-  @DomName('FileWriter.write')
+  @DomName('FileWriter.onwrite')
   @DocsEditable
   Stream<ProgressEvent> get onWrite => writeEvent.forTarget(this);
 
-  @DomName('FileWriter.writeend')
+  @DomName('FileWriter.onwriteend')
   @DocsEditable
   Stream<ProgressEvent> get onWriteEnd => writeEndEvent.forTarget(this);
 
-  @DomName('FileWriter.writestart')
+  @DomName('FileWriter.onwritestart')
   @DocsEditable
   Stream<ProgressEvent> get onWriteStart => writeStartEvent.forTarget(this);
 }
@@ -11391,7 +11392,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(num element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(num element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -11607,7 +11608,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(num element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(num element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -12122,7 +12123,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Node element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Node element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -12329,7 +12330,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Node element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Node element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -12777,38 +12778,31 @@
   }
 
 
-  /**
-   * Stop the current request.
-   *
-   * The request can only be stopped if readyState is `HEADERS_RECIEVED` or
-   * `LOADING`. If this method is not in the process of being sent, the method
-   * has no effect.
-   */
-  @DomName('XMLHttpRequest.abort')
+  @DomName('XMLHttpRequest.abortEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> abortEvent = const EventStreamProvider<ProgressEvent>('abort');
 
-  @DomName('XMLHttpRequest.error')
+  @DomName('XMLHttpRequest.errorEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> errorEvent = const EventStreamProvider<ProgressEvent>('error');
 
-  @DomName('XMLHttpRequest.load')
+  @DomName('XMLHttpRequest.loadEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> loadEvent = const EventStreamProvider<ProgressEvent>('load');
 
-  @DomName('XMLHttpRequest.loadend')
+  @DomName('XMLHttpRequest.loadendEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> loadEndEvent = const EventStreamProvider<ProgressEvent>('loadend');
 
-  @DomName('XMLHttpRequest.loadstart')
+  @DomName('XMLHttpRequest.loadstartEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> loadStartEvent = const EventStreamProvider<ProgressEvent>('loadstart');
 
-  @DomName('XMLHttpRequest.progress')
+  @DomName('XMLHttpRequest.progressEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> progressEvent = const EventStreamProvider<ProgressEvent>('progress');
 
-  @DomName('XMLHttpRequest.readystatechange')
+  @DomName('XMLHttpRequest.readystatechangeEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> readyStateChangeEvent = const EventStreamProvider<ProgressEvent>('readystatechange');
 
@@ -13054,37 +13048,61 @@
   void setRequestHeader(String header, String value) native;
 
   /**
-   * Stop the current request.
-   *
-   * The request can only be stopped if readyState is `HEADERS_RECIEVED` or
-   * `LOADING`. If this method is not in the process of being sent, the method
-   * has no effect.
+   * Event listeners to be notified when request has been aborted,
+   * generally due to calling `httpRequest.abort()`.
    */
-  @DomName('XMLHttpRequest.abort')
+  @DomName('XMLHttpRequest.onabort')
   @DocsEditable
   Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);
 
-  @DomName('XMLHttpRequest.error')
+  /**
+   * Event listeners to be notified when a request has failed, such as when a
+   * cross-domain error occurred or the file wasn't found on the server.
+   */
+  @DomName('XMLHttpRequest.onerror')
   @DocsEditable
   Stream<ProgressEvent> get onError => errorEvent.forTarget(this);
 
-  @DomName('XMLHttpRequest.load')
+  /**
+   * Event listeners to be notified once the request has completed
+   * *successfully*.
+   */
+  @DomName('XMLHttpRequest.onload')
   @DocsEditable
   Stream<ProgressEvent> get onLoad => loadEvent.forTarget(this);
 
-  @DomName('XMLHttpRequest.loadend')
+  /**
+   * Event listeners to be notified once the request has completed (on
+   * either success or failure).
+   */
+  @DomName('XMLHttpRequest.onloadend')
   @DocsEditable
   Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);
 
-  @DomName('XMLHttpRequest.loadstart')
+  /**
+   * Event listeners to be notified when the request starts, once
+   * `httpRequest.send()` has been called.
+   */
+  @DomName('XMLHttpRequest.onloadstart')
   @DocsEditable
   Stream<ProgressEvent> get onLoadStart => loadStartEvent.forTarget(this);
 
-  @DomName('XMLHttpRequest.progress')
+  /**
+   * Event listeners to be notified when data for the request
+   * is being sent or loaded.
+   *
+   * Progress events are fired every 50ms or for every byte transmitted,
+   * whichever is less frequent.
+   */
+  @DomName('XMLHttpRequest.onprogress')
   @DocsEditable
   Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);
 
-  @DomName('XMLHttpRequest.readystatechange')
+  /**
+   * Event listeners to be notified every time the [HttpRequest]
+   * object's `readyState` changes values.
+   */
+  @DomName('XMLHttpRequest.onreadystatechange')
   @DocsEditable
   Stream<ProgressEvent> get onReadyStateChange => readyStateChangeEvent.forTarget(this);
 
@@ -13178,27 +13196,27 @@
 @DomName('XMLHttpRequestUpload')
 class HttpRequestUpload extends EventTarget native "*XMLHttpRequestUpload" {
 
-  @DomName('XMLHttpRequestUpload.abort')
+  @DomName('XMLHttpRequestUpload.abortEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> abortEvent = const EventStreamProvider<ProgressEvent>('abort');
 
-  @DomName('XMLHttpRequestUpload.error')
+  @DomName('XMLHttpRequestUpload.errorEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> errorEvent = const EventStreamProvider<ProgressEvent>('error');
 
-  @DomName('XMLHttpRequestUpload.load')
+  @DomName('XMLHttpRequestUpload.loadEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> loadEvent = const EventStreamProvider<ProgressEvent>('load');
 
-  @DomName('XMLHttpRequestUpload.loadend')
+  @DomName('XMLHttpRequestUpload.loadendEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> loadEndEvent = const EventStreamProvider<ProgressEvent>('loadend');
 
-  @DomName('XMLHttpRequestUpload.loadstart')
+  @DomName('XMLHttpRequestUpload.loadstartEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> loadStartEvent = const EventStreamProvider<ProgressEvent>('loadstart');
 
-  @DomName('XMLHttpRequestUpload.progress')
+  @DomName('XMLHttpRequestUpload.progressEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> progressEvent = const EventStreamProvider<ProgressEvent>('progress');
 
@@ -13222,27 +13240,27 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
 
-  @DomName('XMLHttpRequestUpload.abort')
+  @DomName('XMLHttpRequestUpload.onabort')
   @DocsEditable
   Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);
 
-  @DomName('XMLHttpRequestUpload.error')
+  @DomName('XMLHttpRequestUpload.onerror')
   @DocsEditable
   Stream<ProgressEvent> get onError => errorEvent.forTarget(this);
 
-  @DomName('XMLHttpRequestUpload.load')
+  @DomName('XMLHttpRequestUpload.onload')
   @DocsEditable
   Stream<ProgressEvent> get onLoad => loadEvent.forTarget(this);
 
-  @DomName('XMLHttpRequestUpload.loadend')
+  @DomName('XMLHttpRequestUpload.onloadend')
   @DocsEditable
   Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);
 
-  @DomName('XMLHttpRequestUpload.loadstart')
+  @DomName('XMLHttpRequestUpload.onloadstart')
   @DocsEditable
   Stream<ProgressEvent> get onLoadStart => loadStartEvent.forTarget(this);
 
-  @DomName('XMLHttpRequestUpload.progress')
+  @DomName('XMLHttpRequestUpload.onprogress')
   @DocsEditable
   Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);
 }
@@ -13455,7 +13473,7 @@
     return e;
   }
 
-  @DomName('HTMLInputElement.webkitSpeechChange')
+  @DomName('HTMLInputElement.webkitSpeechChangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> speechChangeEvent = const EventStreamProvider<Event>('webkitSpeechChange');
 
@@ -13695,7 +13713,7 @@
   @DocsEditable
   void stepUp([int n]) native;
 
-  @DomName('HTMLInputElement.webkitSpeechChange')
+  @DomName('HTMLInputElement.onwebkitSpeechChange')
   @DocsEditable
   Stream<Event> get onSpeechChange => speechChangeEvent.forTarget(this);
 
@@ -14348,7 +14366,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(int element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(int element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -14564,7 +14582,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(int element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(int element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -14780,7 +14798,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(int element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(int element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -15458,103 +15476,103 @@
 @DomName('HTMLMediaElement')
 class MediaElement extends Element native "*HTMLMediaElement" {
 
-  @DomName('HTMLMediaElement.canplay')
+  @DomName('HTMLMediaElement.canplayEvent')
   @DocsEditable
   static const EventStreamProvider<Event> canPlayEvent = const EventStreamProvider<Event>('canplay');
 
-  @DomName('HTMLMediaElement.canplaythrough')
+  @DomName('HTMLMediaElement.canplaythroughEvent')
   @DocsEditable
   static const EventStreamProvider<Event> canPlayThroughEvent = const EventStreamProvider<Event>('canplaythrough');
 
-  @DomName('HTMLMediaElement.durationchange')
+  @DomName('HTMLMediaElement.durationchangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> durationChangeEvent = const EventStreamProvider<Event>('durationchange');
 
-  @DomName('HTMLMediaElement.emptied')
+  @DomName('HTMLMediaElement.emptiedEvent')
   @DocsEditable
   static const EventStreamProvider<Event> emptiedEvent = const EventStreamProvider<Event>('emptied');
 
-  @DomName('HTMLMediaElement.ended')
+  @DomName('HTMLMediaElement.endedEvent')
   @DocsEditable
   static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');
 
-  @DomName('HTMLMediaElement.loadeddata')
+  @DomName('HTMLMediaElement.loadeddataEvent')
   @DocsEditable
   static const EventStreamProvider<Event> loadedDataEvent = const EventStreamProvider<Event>('loadeddata');
 
-  @DomName('HTMLMediaElement.loadedmetadata')
+  @DomName('HTMLMediaElement.loadedmetadataEvent')
   @DocsEditable
   static const EventStreamProvider<Event> loadedMetadataEvent = const EventStreamProvider<Event>('loadedmetadata');
 
-  @DomName('HTMLMediaElement.loadstart')
+  @DomName('HTMLMediaElement.loadstartEvent')
   @DocsEditable
   static const EventStreamProvider<Event> loadStartEvent = const EventStreamProvider<Event>('loadstart');
 
-  @DomName('HTMLMediaElement.pause')
+  @DomName('HTMLMediaElement.pauseEvent')
   @DocsEditable
   static const EventStreamProvider<Event> pauseEvent = const EventStreamProvider<Event>('pause');
 
-  @DomName('HTMLMediaElement.play')
+  @DomName('HTMLMediaElement.playEvent')
   @DocsEditable
   static const EventStreamProvider<Event> playEvent = const EventStreamProvider<Event>('play');
 
-  @DomName('HTMLMediaElement.playing')
+  @DomName('HTMLMediaElement.playingEvent')
   @DocsEditable
   static const EventStreamProvider<Event> playingEvent = const EventStreamProvider<Event>('playing');
 
-  @DomName('HTMLMediaElement.progress')
+  @DomName('HTMLMediaElement.progressEvent')
   @DocsEditable
   static const EventStreamProvider<Event> progressEvent = const EventStreamProvider<Event>('progress');
 
-  @DomName('HTMLMediaElement.ratechange')
+  @DomName('HTMLMediaElement.ratechangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> rateChangeEvent = const EventStreamProvider<Event>('ratechange');
 
-  @DomName('HTMLMediaElement.seeked')
+  @DomName('HTMLMediaElement.seekedEvent')
   @DocsEditable
   static const EventStreamProvider<Event> seekedEvent = const EventStreamProvider<Event>('seeked');
 
-  @DomName('HTMLMediaElement.seeking')
+  @DomName('HTMLMediaElement.seekingEvent')
   @DocsEditable
   static const EventStreamProvider<Event> seekingEvent = const EventStreamProvider<Event>('seeking');
 
-  @DomName('HTMLMediaElement.show')
+  @DomName('HTMLMediaElement.showEvent')
   @DocsEditable
   static const EventStreamProvider<Event> showEvent = const EventStreamProvider<Event>('show');
 
-  @DomName('HTMLMediaElement.stalled')
+  @DomName('HTMLMediaElement.stalledEvent')
   @DocsEditable
   static const EventStreamProvider<Event> stalledEvent = const EventStreamProvider<Event>('stalled');
 
-  @DomName('HTMLMediaElement.suspend')
+  @DomName('HTMLMediaElement.suspendEvent')
   @DocsEditable
   static const EventStreamProvider<Event> suspendEvent = const EventStreamProvider<Event>('suspend');
 
-  @DomName('HTMLMediaElement.timeupdate')
+  @DomName('HTMLMediaElement.timeupdateEvent')
   @DocsEditable
   static const EventStreamProvider<Event> timeUpdateEvent = const EventStreamProvider<Event>('timeupdate');
 
-  @DomName('HTMLMediaElement.volumechange')
+  @DomName('HTMLMediaElement.volumechangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> volumeChangeEvent = const EventStreamProvider<Event>('volumechange');
 
-  @DomName('HTMLMediaElement.waiting')
+  @DomName('HTMLMediaElement.waitingEvent')
   @DocsEditable
   static const EventStreamProvider<Event> waitingEvent = const EventStreamProvider<Event>('waiting');
 
-  @DomName('HTMLMediaElement.webkitkeyadded')
+  @DomName('HTMLMediaElement.webkitkeyaddedEvent')
   @DocsEditable
   static const EventStreamProvider<MediaKeyEvent> keyAddedEvent = const EventStreamProvider<MediaKeyEvent>('webkitkeyadded');
 
-  @DomName('HTMLMediaElement.webkitkeyerror')
+  @DomName('HTMLMediaElement.webkitkeyerrorEvent')
   @DocsEditable
   static const EventStreamProvider<MediaKeyEvent> keyErrorEvent = const EventStreamProvider<MediaKeyEvent>('webkitkeyerror');
 
-  @DomName('HTMLMediaElement.webkitkeymessage')
+  @DomName('HTMLMediaElement.webkitkeymessageEvent')
   @DocsEditable
   static const EventStreamProvider<MediaKeyEvent> keyMessageEvent = const EventStreamProvider<MediaKeyEvent>('webkitkeymessage');
 
-  @DomName('HTMLMediaElement.webkitneedkey')
+  @DomName('HTMLMediaElement.webkitneedkeyEvent')
   @DocsEditable
   static const EventStreamProvider<MediaKeyEvent> needKeyEvent = const EventStreamProvider<MediaKeyEvent>('webkitneedkey');
 
@@ -15742,103 +15760,103 @@
   @DocsEditable
   void webkitGenerateKeyRequest(String keySystem, [Uint8Array initData]) native;
 
-  @DomName('HTMLMediaElement.canplay')
+  @DomName('HTMLMediaElement.oncanplay')
   @DocsEditable
   Stream<Event> get onCanPlay => canPlayEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.canplaythrough')
+  @DomName('HTMLMediaElement.oncanplaythrough')
   @DocsEditable
   Stream<Event> get onCanPlayThrough => canPlayThroughEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.durationchange')
+  @DomName('HTMLMediaElement.ondurationchange')
   @DocsEditable
   Stream<Event> get onDurationChange => durationChangeEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.emptied')
+  @DomName('HTMLMediaElement.onemptied')
   @DocsEditable
   Stream<Event> get onEmptied => emptiedEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.ended')
+  @DomName('HTMLMediaElement.onended')
   @DocsEditable
   Stream<Event> get onEnded => endedEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.loadeddata')
+  @DomName('HTMLMediaElement.onloadeddata')
   @DocsEditable
   Stream<Event> get onLoadedData => loadedDataEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.loadedmetadata')
+  @DomName('HTMLMediaElement.onloadedmetadata')
   @DocsEditable
   Stream<Event> get onLoadedMetadata => loadedMetadataEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.loadstart')
+  @DomName('HTMLMediaElement.onloadstart')
   @DocsEditable
   Stream<Event> get onLoadStart => loadStartEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.pause')
+  @DomName('HTMLMediaElement.onpause')
   @DocsEditable
   Stream<Event> get onPause => pauseEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.play')
+  @DomName('HTMLMediaElement.onplay')
   @DocsEditable
   Stream<Event> get onPlay => playEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.playing')
+  @DomName('HTMLMediaElement.onplaying')
   @DocsEditable
   Stream<Event> get onPlaying => playingEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.progress')
+  @DomName('HTMLMediaElement.onprogress')
   @DocsEditable
   Stream<Event> get onProgress => progressEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.ratechange')
+  @DomName('HTMLMediaElement.onratechange')
   @DocsEditable
   Stream<Event> get onRateChange => rateChangeEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.seeked')
+  @DomName('HTMLMediaElement.onseeked')
   @DocsEditable
   Stream<Event> get onSeeked => seekedEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.seeking')
+  @DomName('HTMLMediaElement.onseeking')
   @DocsEditable
   Stream<Event> get onSeeking => seekingEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.show')
+  @DomName('HTMLMediaElement.onshow')
   @DocsEditable
   Stream<Event> get onShow => showEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.stalled')
+  @DomName('HTMLMediaElement.onstalled')
   @DocsEditable
   Stream<Event> get onStalled => stalledEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.suspend')
+  @DomName('HTMLMediaElement.onsuspend')
   @DocsEditable
   Stream<Event> get onSuspend => suspendEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.timeupdate')
+  @DomName('HTMLMediaElement.ontimeupdate')
   @DocsEditable
   Stream<Event> get onTimeUpdate => timeUpdateEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.volumechange')
+  @DomName('HTMLMediaElement.onvolumechange')
   @DocsEditable
   Stream<Event> get onVolumeChange => volumeChangeEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.waiting')
+  @DomName('HTMLMediaElement.onwaiting')
   @DocsEditable
   Stream<Event> get onWaiting => waitingEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.webkitkeyadded')
+  @DomName('HTMLMediaElement.onwebkitkeyadded')
   @DocsEditable
   Stream<MediaKeyEvent> get onKeyAdded => keyAddedEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.webkitkeyerror')
+  @DomName('HTMLMediaElement.onwebkitkeyerror')
   @DocsEditable
   Stream<MediaKeyEvent> get onKeyError => keyErrorEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.webkitkeymessage')
+  @DomName('HTMLMediaElement.onwebkitkeymessage')
   @DocsEditable
   Stream<MediaKeyEvent> get onKeyMessage => keyMessageEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.webkitneedkey')
+  @DomName('HTMLMediaElement.onwebkitneedkey')
   @DocsEditable
   Stream<MediaKeyEvent> get onNeedKey => needKeyEvent.forTarget(this);
 }
@@ -16141,7 +16159,7 @@
 
 class MediaStream extends EventTarget native "*MediaStream" {
 
-  @DomName('MediaStream.ended')
+  @DomName('MediaStream.endedEvent')
   @DocsEditable
   static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');
 
@@ -16215,7 +16233,7 @@
   @DocsEditable
   void removeTrack(MediaStreamTrack track) native;
 
-  @DomName('MediaStream.ended')
+  @DomName('MediaStream.onended')
   @DocsEditable
   Stream<Event> get onEnded => endedEvent.forTarget(this);
 
@@ -16276,15 +16294,15 @@
 @DomName('MediaStreamTrack')
 class MediaStreamTrack extends EventTarget native "*MediaStreamTrack" {
 
-  @DomName('MediaStreamTrack.ended')
+  @DomName('MediaStreamTrack.endedEvent')
   @DocsEditable
   static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');
 
-  @DomName('MediaStreamTrack.mute')
+  @DomName('MediaStreamTrack.muteEvent')
   @DocsEditable
   static const EventStreamProvider<Event> muteEvent = const EventStreamProvider<Event>('mute');
 
-  @DomName('MediaStreamTrack.unmute')
+  @DomName('MediaStreamTrack.unmuteEvent')
   @DocsEditable
   static const EventStreamProvider<Event> unmuteEvent = const EventStreamProvider<Event>('unmute');
 
@@ -16328,15 +16346,15 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
 
-  @DomName('MediaStreamTrack.ended')
+  @DomName('MediaStreamTrack.onended')
   @DocsEditable
   Stream<Event> get onEnded => endedEvent.forTarget(this);
 
-  @DomName('MediaStreamTrack.mute')
+  @DomName('MediaStreamTrack.onmute')
   @DocsEditable
   Stream<Event> get onMute => muteEvent.forTarget(this);
 
-  @DomName('MediaStreamTrack.unmute')
+  @DomName('MediaStreamTrack.onunmute')
   @DocsEditable
   Stream<Event> get onUnmute => unmuteEvent.forTarget(this);
 }
@@ -16399,6 +16417,16 @@
 
 
 @DocsEditable
+/**
+ * An HTML <menu> element.
+ *
+ * A <menu> element represents an unordered list of menu commands.
+ *
+ * See also:
+ *
+ *  * [Menu Element](https://developer.mozilla.org/en-US/docs/HTML/Element/menu) from MDN.
+ *  * [Menu Element](http://www.w3.org/TR/html5/the-menu-element.html#the-menu-element) from the W3C.
+ */
 @DomName('HTMLMenuElement')
 class MenuElement extends Element native "*HTMLMenuElement" {
 
@@ -16496,7 +16524,7 @@
 @DomName('MessagePort')
 class MessagePort extends EventTarget native "*MessagePort" {
 
-  @DomName('MessagePort.message')
+  @DomName('MessagePort.messageEvent')
   @DocsEditable
   static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
 
@@ -16547,7 +16575,7 @@
   @DocsEditable
   void start() native;
 
-  @DomName('MessagePort.message')
+  @DomName('MessagePort.onmessage')
   @DocsEditable
   Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
 }
@@ -16779,6 +16807,15 @@
   void _$dom_initMouseEvent_1(type, canBubble, cancelable, Window view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget) native;
 
 
+  // TODO(amouravski): Move this documentation out of thise template files and
+  // put it into docs.json. Remember to add @DomName here.
+  /**
+   * The X coordinate of the mouse pointer in target node coordinates.
+   *
+   * This value may vary between platforms if the target node moves
+   * after the event has fired or if the element has CSS transforms affecting
+   * it.
+   */
   int get offsetX {
   if (JS('bool', '!!#.offsetX', this)) {
       return JS('int', '#.offsetX', this);
@@ -16793,6 +16830,13 @@
     }
   }
 
+  /**
+   * The Y coordinate of the mouse pointer in target node coordinates.
+   *
+   * This value may vary between platforms if the target node moves
+   * after the event has fired or if the element has CSS transforms affecting
+   * it.
+   */
   int get offsetY {
     if (JS('bool', '!!#.offsetY', this)) {
       return JS('int', '#.offsetY', this);
@@ -17069,7 +17113,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Node element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Node element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -17539,7 +17583,7 @@
   }
 
   Iterable map(f(Node element)) {
-    return IterableMixinWorkaround.map(this, f);
+    return IterableMixinWorkaround.mapList(this, f);
   }
 
   List mappedBy(f(Node element)) {
@@ -17931,7 +17975,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Node element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Node element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -18113,23 +18157,23 @@
 @DomName('Notification')
 class Notification extends EventTarget native "*Notification" {
 
-  @DomName('Notification.click')
+  @DomName('Notification.clickEvent')
   @DocsEditable
   static const EventStreamProvider<Event> clickEvent = const EventStreamProvider<Event>('click');
 
-  @DomName('Notification.close')
+  @DomName('Notification.closeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> closeEvent = const EventStreamProvider<Event>('close');
 
-  @DomName('Notification.display')
+  @DomName('Notification.displayEvent')
   @DocsEditable
   static const EventStreamProvider<Event> displayEvent = const EventStreamProvider<Event>('display');
 
-  @DomName('Notification.error')
+  @DomName('Notification.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('Notification.show')
+  @DomName('Notification.showEvent')
   @DocsEditable
   static const EventStreamProvider<Event> showEvent = const EventStreamProvider<Event>('show');
 
@@ -18196,23 +18240,23 @@
   @DocsEditable
   void show() native;
 
-  @DomName('Notification.click')
+  @DomName('Notification.onclick')
   @DocsEditable
   Stream<Event> get onClick => clickEvent.forTarget(this);
 
-  @DomName('Notification.close')
+  @DomName('Notification.onclose')
   @DocsEditable
   Stream<Event> get onClose => closeEvent.forTarget(this);
 
-  @DomName('Notification.display')
+  @DomName('Notification.ondisplay')
   @DocsEditable
   Stream<Event> get onDisplay => displayEvent.forTarget(this);
 
-  @DomName('Notification.error')
+  @DomName('Notification.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('Notification.show')
+  @DomName('Notification.onshow')
   @DocsEditable
   Stream<Event> get onShow => showEvent.forTarget(this);
 }
@@ -18311,7 +18355,7 @@
 @DocsEditable
 @DomName('HTMLObjectElement')
 @SupportedBrowser(SupportedBrowser.CHROME)
-@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE)
 @SupportedBrowser(SupportedBrowser.SAFARI)
 class ObjectElement extends Element native "*HTMLObjectElement" {
 
@@ -19286,19 +19330,19 @@
 @DomName('RTCDataChannel')
 class RtcDataChannel extends EventTarget native "*RTCDataChannel" {
 
-  @DomName('RTCDataChannel.close')
+  @DomName('RTCDataChannel.closeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> closeEvent = const EventStreamProvider<Event>('close');
 
-  @DomName('RTCDataChannel.error')
+  @DomName('RTCDataChannel.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('RTCDataChannel.message')
+  @DomName('RTCDataChannel.messageEvent')
   @DocsEditable
   static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
 
-  @DomName('RTCDataChannel.open')
+  @DomName('RTCDataChannel.openEvent')
   @DocsEditable
   static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');
 
@@ -19350,19 +19394,19 @@
   @DocsEditable
   void send(data) native;
 
-  @DomName('RTCDataChannel.close')
+  @DomName('RTCDataChannel.onclose')
   @DocsEditable
   Stream<Event> get onClose => closeEvent.forTarget(this);
 
-  @DomName('RTCDataChannel.error')
+  @DomName('RTCDataChannel.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('RTCDataChannel.message')
+  @DomName('RTCDataChannel.onmessage')
   @DocsEditable
   Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
 
-  @DomName('RTCDataChannel.open')
+  @DomName('RTCDataChannel.onopen')
   @DocsEditable
   Stream<Event> get onOpen => openEvent.forTarget(this);
 }
@@ -19448,31 +19492,31 @@
 @DomName('RTCPeerConnection')
 class RtcPeerConnection extends EventTarget native "*RTCPeerConnection" {
 
-  @DomName('RTCPeerConnection.addstream')
+  @DomName('RTCPeerConnection.addstreamEvent')
   @DocsEditable
   static const EventStreamProvider<MediaStreamEvent> addStreamEvent = const EventStreamProvider<MediaStreamEvent>('addstream');
 
-  @DomName('RTCPeerConnection.datachannel')
+  @DomName('RTCPeerConnection.datachannelEvent')
   @DocsEditable
   static const EventStreamProvider<RtcDataChannelEvent> dataChannelEvent = const EventStreamProvider<RtcDataChannelEvent>('datachannel');
 
-  @DomName('RTCPeerConnection.icecandidate')
+  @DomName('RTCPeerConnection.icecandidateEvent')
   @DocsEditable
   static const EventStreamProvider<RtcIceCandidateEvent> iceCandidateEvent = const EventStreamProvider<RtcIceCandidateEvent>('icecandidate');
 
-  @DomName('RTCPeerConnection.icechange')
+  @DomName('RTCPeerConnection.icechangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> iceChangeEvent = const EventStreamProvider<Event>('icechange');
 
-  @DomName('RTCPeerConnection.negotiationneeded')
+  @DomName('RTCPeerConnection.negotiationneededEvent')
   @DocsEditable
   static const EventStreamProvider<Event> negotiationNeededEvent = const EventStreamProvider<Event>('negotiationneeded');
 
-  @DomName('RTCPeerConnection.removestream')
+  @DomName('RTCPeerConnection.removestreamEvent')
   @DocsEditable
   static const EventStreamProvider<MediaStreamEvent> removeStreamEvent = const EventStreamProvider<MediaStreamEvent>('removestream');
 
-  @DomName('RTCPeerConnection.statechange')
+  @DomName('RTCPeerConnection.statechangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> stateChangeEvent = const EventStreamProvider<Event>('statechange');
 
@@ -19665,31 +19709,31 @@
   @DocsEditable
   void _updateIce_3() native;
 
-  @DomName('RTCPeerConnection.addstream')
+  @DomName('RTCPeerConnection.onaddstream')
   @DocsEditable
   Stream<MediaStreamEvent> get onAddStream => addStreamEvent.forTarget(this);
 
-  @DomName('RTCPeerConnection.datachannel')
+  @DomName('RTCPeerConnection.ondatachannel')
   @DocsEditable
   Stream<RtcDataChannelEvent> get onDataChannel => dataChannelEvent.forTarget(this);
 
-  @DomName('RTCPeerConnection.icecandidate')
+  @DomName('RTCPeerConnection.onicecandidate')
   @DocsEditable
   Stream<RtcIceCandidateEvent> get onIceCandidate => iceCandidateEvent.forTarget(this);
 
-  @DomName('RTCPeerConnection.icechange')
+  @DomName('RTCPeerConnection.onicechange')
   @DocsEditable
   Stream<Event> get onIceChange => iceChangeEvent.forTarget(this);
 
-  @DomName('RTCPeerConnection.negotiationneeded')
+  @DomName('RTCPeerConnection.onnegotiationneeded')
   @DocsEditable
   Stream<Event> get onNegotiationNeeded => negotiationNeededEvent.forTarget(this);
 
-  @DomName('RTCPeerConnection.removestream')
+  @DomName('RTCPeerConnection.onremovestream')
   @DocsEditable
   Stream<MediaStreamEvent> get onRemoveStream => removeStreamEvent.forTarget(this);
 
-  @DomName('RTCPeerConnection.statechange')
+  @DomName('RTCPeerConnection.onstatechange')
   @DocsEditable
   Stream<Event> get onStateChange => stateChangeEvent.forTarget(this);
 }
@@ -20219,7 +20263,7 @@
 @DomName('SharedWorkerContext')
 class SharedWorkerContext extends WorkerContext native "*SharedWorkerContext" {
 
-  @DomName('SharedWorkerContext.connect')
+  @DomName('SharedWorkerContext.connectEvent')
   @DocsEditable
   static const EventStreamProvider<Event> connectEvent = const EventStreamProvider<Event>('connect');
 
@@ -20233,7 +20277,7 @@
   @DocsEditable
   final String name;
 
-  @DomName('SharedWorkerContext.connect')
+  @DomName('SharedWorkerContext.onconnect')
   @DocsEditable
   Stream<Event> get onConnect => connectEvent.forTarget(this);
 }
@@ -20314,7 +20358,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(SourceBuffer element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(SourceBuffer element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -20594,7 +20638,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(SpeechGrammar element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(SpeechGrammar element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -20799,47 +20843,47 @@
 @Experimental
 class SpeechRecognition extends EventTarget native "*SpeechRecognition" {
 
-  @DomName('SpeechRecognition.audioend')
+  @DomName('SpeechRecognition.audioendEvent')
   @DocsEditable
   static const EventStreamProvider<Event> audioEndEvent = const EventStreamProvider<Event>('audioend');
 
-  @DomName('SpeechRecognition.audiostart')
+  @DomName('SpeechRecognition.audiostartEvent')
   @DocsEditable
   static const EventStreamProvider<Event> audioStartEvent = const EventStreamProvider<Event>('audiostart');
 
-  @DomName('SpeechRecognition.end')
+  @DomName('SpeechRecognition.endEvent')
   @DocsEditable
   static const EventStreamProvider<Event> endEvent = const EventStreamProvider<Event>('end');
 
-  @DomName('SpeechRecognition.error')
+  @DomName('SpeechRecognition.errorEvent')
   @DocsEditable
   static const EventStreamProvider<SpeechRecognitionError> errorEvent = const EventStreamProvider<SpeechRecognitionError>('error');
 
-  @DomName('SpeechRecognition.nomatch')
+  @DomName('SpeechRecognition.nomatchEvent')
   @DocsEditable
   static const EventStreamProvider<SpeechRecognitionEvent> noMatchEvent = const EventStreamProvider<SpeechRecognitionEvent>('nomatch');
 
-  @DomName('SpeechRecognition.result')
+  @DomName('SpeechRecognition.resultEvent')
   @DocsEditable
   static const EventStreamProvider<SpeechRecognitionEvent> resultEvent = const EventStreamProvider<SpeechRecognitionEvent>('result');
 
-  @DomName('SpeechRecognition.soundend')
+  @DomName('SpeechRecognition.soundendEvent')
   @DocsEditable
   static const EventStreamProvider<Event> soundEndEvent = const EventStreamProvider<Event>('soundend');
 
-  @DomName('SpeechRecognition.soundstart')
+  @DomName('SpeechRecognition.soundstartEvent')
   @DocsEditable
   static const EventStreamProvider<Event> soundStartEvent = const EventStreamProvider<Event>('soundstart');
 
-  @DomName('SpeechRecognition.speechend')
+  @DomName('SpeechRecognition.speechendEvent')
   @DocsEditable
   static const EventStreamProvider<Event> speechEndEvent = const EventStreamProvider<Event>('speechend');
 
-  @DomName('SpeechRecognition.speechstart')
+  @DomName('SpeechRecognition.speechstartEvent')
   @DocsEditable
   static const EventStreamProvider<Event> speechStartEvent = const EventStreamProvider<Event>('speechstart');
 
-  @DomName('SpeechRecognition.start')
+  @DomName('SpeechRecognition.startEvent')
   @DocsEditable
   static const EventStreamProvider<Event> startEvent = const EventStreamProvider<Event>('start');
 
@@ -20898,47 +20942,47 @@
   @DocsEditable
   void stop() native;
 
-  @DomName('SpeechRecognition.audioend')
+  @DomName('SpeechRecognition.onaudioend')
   @DocsEditable
   Stream<Event> get onAudioEnd => audioEndEvent.forTarget(this);
 
-  @DomName('SpeechRecognition.audiostart')
+  @DomName('SpeechRecognition.onaudiostart')
   @DocsEditable
   Stream<Event> get onAudioStart => audioStartEvent.forTarget(this);
 
-  @DomName('SpeechRecognition.end')
+  @DomName('SpeechRecognition.onend')
   @DocsEditable
   Stream<Event> get onEnd => endEvent.forTarget(this);
 
-  @DomName('SpeechRecognition.error')
+  @DomName('SpeechRecognition.onerror')
   @DocsEditable
   Stream<SpeechRecognitionError> get onError => errorEvent.forTarget(this);
 
-  @DomName('SpeechRecognition.nomatch')
+  @DomName('SpeechRecognition.onnomatch')
   @DocsEditable
   Stream<SpeechRecognitionEvent> get onNoMatch => noMatchEvent.forTarget(this);
 
-  @DomName('SpeechRecognition.result')
+  @DomName('SpeechRecognition.onresult')
   @DocsEditable
   Stream<SpeechRecognitionEvent> get onResult => resultEvent.forTarget(this);
 
-  @DomName('SpeechRecognition.soundend')
+  @DomName('SpeechRecognition.onsoundend')
   @DocsEditable
   Stream<Event> get onSoundEnd => soundEndEvent.forTarget(this);
 
-  @DomName('SpeechRecognition.soundstart')
+  @DomName('SpeechRecognition.onsoundstart')
   @DocsEditable
   Stream<Event> get onSoundStart => soundStartEvent.forTarget(this);
 
-  @DomName('SpeechRecognition.speechend')
+  @DomName('SpeechRecognition.onspeechend')
   @DocsEditable
   Stream<Event> get onSpeechEnd => speechEndEvent.forTarget(this);
 
-  @DomName('SpeechRecognition.speechstart')
+  @DomName('SpeechRecognition.onspeechstart')
   @DocsEditable
   Stream<Event> get onSpeechStart => speechStartEvent.forTarget(this);
 
-  @DomName('SpeechRecognition.start')
+  @DomName('SpeechRecognition.onstart')
   @DocsEditable
   Stream<Event> get onStart => startEvent.forTarget(this);
 
@@ -21208,7 +21252,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Map element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Map element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -21405,6 +21449,31 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
+/**
+ * The type used by the
+ * [Window.localStorage] and [Window.sessionStorage] properties.
+ * Storage is implemented as a Map&lt;String, String>.
+ *
+ * To store and get values, use Dart's built-in map syntax:
+ *
+ *     window.localStorage['key1'] = 'val1';
+ *     window.localStorage['key2'] = 'val2';
+ *     window.localStorage['key3'] = 'val3';
+ *     assert(window.localStorage['key3'] == 'val3');
+ *
+ * You can use [Map](http://api.dartlang.org/dart_core/Map.html) APIs
+ * such as containsValue(), clear(), and length:
+ *
+ *     assert(window.localStorage.containsValue('does not exist') == false);
+ *     window.localStorage.clear();
+ *     assert(window.localStorage.length == 0);
+ *
+ * For more examples of using this API, see
+ * [localstorage_test.dart](http://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/tests/html/localstorage_test.dart).
+ * For details on using the Map API, see the
+ * [Maps](http://www.dartlang.org/docs/library-tour/#maps-aka-dictionaries-or-hashes)
+ * section of the library tour.
+ */
 @DomName('Storage')
 class Storage implements Map<String, String>
      native "*Storage" {
@@ -21805,7 +21874,7 @@
       return this._createTBody();
     }
     var tbody = new Element.tag('tbody');
-    this.elements.add(tbody);
+    this.children.add(tbody);
     return tbody;
   }
 
@@ -22068,7 +22137,7 @@
 @DomName('TextTrack')
 class TextTrack extends EventTarget native "*TextTrack" {
 
-  @DomName('TextTrack.cuechange')
+  @DomName('TextTrack.cuechangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> cueChangeEvent = const EventStreamProvider<Event>('cuechange');
 
@@ -22124,7 +22193,7 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
 
-  @DomName('TextTrack.cuechange')
+  @DomName('TextTrack.oncuechange')
   @DocsEditable
   Stream<Event> get onCueChange => cueChangeEvent.forTarget(this);
 }
@@ -22147,11 +22216,11 @@
 @DomName('TextTrackCue')
 class TextTrackCue extends EventTarget native "*TextTrackCue" {
 
-  @DomName('TextTrackCue.enter')
+  @DomName('TextTrackCue.enterEvent')
   @DocsEditable
   static const EventStreamProvider<Event> enterEvent = const EventStreamProvider<Event>('enter');
 
-  @DomName('TextTrackCue.exit')
+  @DomName('TextTrackCue.exitEvent')
   @DocsEditable
   static const EventStreamProvider<Event> exitEvent = const EventStreamProvider<Event>('exit');
 
@@ -22235,11 +22304,11 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
 
-  @DomName('TextTrackCue.enter')
+  @DomName('TextTrackCue.onenter')
   @DocsEditable
   Stream<Event> get onEnter => enterEvent.forTarget(this);
 
-  @DomName('TextTrackCue.exit')
+  @DomName('TextTrackCue.onexit')
   @DocsEditable
   Stream<Event> get onExit => exitEvent.forTarget(this);
 }
@@ -22298,7 +22367,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(TextTrackCue element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(TextTrackCue element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -22466,7 +22535,7 @@
 @DomName('TextTrackList')
 class TextTrackList extends EventTarget implements JavaScriptIndexingBehavior, List<TextTrack> native "*TextTrackList" {
 
-  @DomName('TextTrackList.addtrack')
+  @DomName('TextTrackList.addtrackEvent')
   @DocsEditable
   static const EventStreamProvider<TrackEvent> addTrackEvent = const EventStreamProvider<TrackEvent>('addtrack');
 
@@ -22509,7 +22578,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(TextTrack element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(TextTrack element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -22678,7 +22747,7 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
 
-  @DomName('TextTrackList.addtrack')
+  @DomName('TextTrackList.onaddtrack')
   @DocsEditable
   Stream<TrackEvent> get onAddTrack => addTrackEvent.forTarget(this);
 }
@@ -22865,14 +22934,22 @@
     return false;
   }
 }
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
+// WARNING: Do not edit - generated code.
 
-@DocsEditable
+
 @DomName('TouchList')
 class TouchList implements JavaScriptIndexingBehavior, List<Touch> native "*TouchList" {
+  /// NB: This constructor likely does not work as you might expect it to! This
+  /// constructor will simply fail (returning null) if you are not on a device
+  /// with touch enabled. See dartbug.com/8314.
+  factory TouchList() => document.$dom_createTouchList();
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!document.createTouchList');
 
   @DomName('TouchList.length')
   @DocsEditable
@@ -22907,7 +22984,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Touch element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Touch element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -23061,6 +23138,7 @@
   @DomName('TouchList.item')
   @DocsEditable
   Touch item(int index) native;
+
 }
 // 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
@@ -23348,7 +23426,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(int element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(int element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -23564,7 +23642,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(int element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(int element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -23780,7 +23858,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(int element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(int element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -23993,7 +24071,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(int element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(int element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -25881,6 +25959,40 @@
 
 
 @DocsEditable
+/**
+ * Use the WebSocket interface to connect to a WebSocket,
+ * and to send and receive data on that WebSocket.
+ *
+ * To use a WebSocket in your web app, first create a WebSocket object,
+ * passing the WebSocket URL as an argument to the constructor.
+ *
+ *     var webSocket = new WebSocket('ws://127.0.0.1:1337/ws');
+ *
+ * To send data on the WebSocket, use the [send] method.
+ *
+ *     if (webSocket != null && webSocket.readyState == WebSocket.OPEN) {
+ *       webSocket.send(data);
+ *     } else {
+ *       print('WebSocket not connected, message $data not sent');
+ *     }
+ *
+ * To receive data on the WebSocket, register a listener for message events.
+ *
+ *     webSocket.on.message.add((MessageEvent e) {
+ *       receivedData(e.data);
+ *     });
+ *
+ * The message event handler receives a [MessageEvent] object
+ * as its sole argument.
+ * You can also define open, close, and error handlers,
+ * as specified by [WebSocketEvents].
+ *
+ * For more information, see the
+ * [WebSockets](http://www.dartlang.org/docs/library-tour/#html-websockets)
+ * section of the library tour and
+ * [Introducing WebSockets](http://www.html5rocks.com/en/tutorials/websockets/basics/),
+ * an HTML5Rocks.com tutorial.
+ */
 @DomName('WebSocket')
 @SupportedBrowser(SupportedBrowser.CHROME)
 @SupportedBrowser(SupportedBrowser.FIREFOX)
@@ -25888,19 +26000,19 @@
 @SupportedBrowser(SupportedBrowser.SAFARI)
 class WebSocket extends EventTarget native "*WebSocket" {
 
-  @DomName('WebSocket.close')
+  @DomName('WebSocket.closeEvent')
   @DocsEditable
   static const EventStreamProvider<CloseEvent> closeEvent = const EventStreamProvider<CloseEvent>('close');
 
-  @DomName('WebSocket.error')
+  @DomName('WebSocket.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('WebSocket.message')
+  @DomName('WebSocket.messageEvent')
   @DocsEditable
   static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
 
-  @DomName('WebSocket.open')
+  @DomName('WebSocket.openEvent')
   @DocsEditable
   static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');
 
@@ -25990,19 +26102,19 @@
   @DocsEditable
   void send(data) native;
 
-  @DomName('WebSocket.close')
+  @DomName('WebSocket.onclose')
   @DocsEditable
   Stream<CloseEvent> get onClose => closeEvent.forTarget(this);
 
-  @DomName('WebSocket.error')
+  @DomName('WebSocket.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('WebSocket.message')
+  @DomName('WebSocket.onmessage')
   @DocsEditable
   Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
 
-  @DomName('WebSocket.open')
+  @DomName('WebSocket.onopen')
   @DocsEditable
   Stream<Event> get onOpen => openEvent.forTarget(this);
 }
@@ -26396,71 +26508,71 @@
   }
 
 
-  @DomName('DOMWindow.DOMContentLoaded')
+  @DomName('DOMWindow.DOMContentLoadedEvent')
   @DocsEditable
   static const EventStreamProvider<Event> contentLoadedEvent = const EventStreamProvider<Event>('DOMContentLoaded');
 
-  @DomName('DOMWindow.beforeunload')
+  @DomName('DOMWindow.beforeunloadEvent')
   @DocsEditable
   static const EventStreamProvider<Event> beforeUnloadEvent = const EventStreamProvider<Event>('beforeunload');
 
-  @DomName('DOMWindow.devicemotion')
+  @DomName('DOMWindow.devicemotionEvent')
   @DocsEditable
   static const EventStreamProvider<DeviceMotionEvent> deviceMotionEvent = const EventStreamProvider<DeviceMotionEvent>('devicemotion');
 
-  @DomName('DOMWindow.deviceorientation')
+  @DomName('DOMWindow.deviceorientationEvent')
   @DocsEditable
   static const EventStreamProvider<DeviceOrientationEvent> deviceOrientationEvent = const EventStreamProvider<DeviceOrientationEvent>('deviceorientation');
 
-  @DomName('DOMWindow.hashchange')
+  @DomName('DOMWindow.hashchangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> hashChangeEvent = const EventStreamProvider<Event>('hashchange');
 
-  @DomName('DOMWindow.message')
+  @DomName('DOMWindow.messageEvent')
   @DocsEditable
   static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
 
-  @DomName('DOMWindow.offline')
+  @DomName('DOMWindow.offlineEvent')
   @DocsEditable
   static const EventStreamProvider<Event> offlineEvent = const EventStreamProvider<Event>('offline');
 
-  @DomName('DOMWindow.online')
+  @DomName('DOMWindow.onlineEvent')
   @DocsEditable
   static const EventStreamProvider<Event> onlineEvent = const EventStreamProvider<Event>('online');
 
-  @DomName('DOMWindow.pagehide')
+  @DomName('DOMWindow.pagehideEvent')
   @DocsEditable
   static const EventStreamProvider<Event> pageHideEvent = const EventStreamProvider<Event>('pagehide');
 
-  @DomName('DOMWindow.pageshow')
+  @DomName('DOMWindow.pageshowEvent')
   @DocsEditable
   static const EventStreamProvider<Event> pageShowEvent = const EventStreamProvider<Event>('pageshow');
 
-  @DomName('DOMWindow.popstate')
+  @DomName('DOMWindow.popstateEvent')
   @DocsEditable
   static const EventStreamProvider<PopStateEvent> popStateEvent = const EventStreamProvider<PopStateEvent>('popstate');
 
-  @DomName('DOMWindow.resize')
+  @DomName('DOMWindow.resizeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');
 
-  @DomName('DOMWindow.storage')
+  @DomName('DOMWindow.storageEvent')
   @DocsEditable
   static const EventStreamProvider<StorageEvent> storageEvent = const EventStreamProvider<StorageEvent>('storage');
 
-  @DomName('DOMWindow.unload')
+  @DomName('DOMWindow.unloadEvent')
   @DocsEditable
   static const EventStreamProvider<Event> unloadEvent = const EventStreamProvider<Event>('unload');
 
-  @DomName('DOMWindow.webkitAnimationEnd')
+  @DomName('DOMWindow.webkitAnimationEndEvent')
   @DocsEditable
   static const EventStreamProvider<AnimationEvent> animationEndEvent = const EventStreamProvider<AnimationEvent>('webkitAnimationEnd');
 
-  @DomName('DOMWindow.webkitAnimationIteration')
+  @DomName('DOMWindow.webkitAnimationIterationEvent')
   @DocsEditable
   static const EventStreamProvider<AnimationEvent> animationIterationEvent = const EventStreamProvider<AnimationEvent>('webkitAnimationIteration');
 
-  @DomName('DOMWindow.webkitAnimationStart')
+  @DomName('DOMWindow.webkitAnimationStartEvent')
   @DocsEditable
   static const EventStreamProvider<AnimationEvent> animationStartEvent = const EventStreamProvider<AnimationEvent>('webkitAnimationStart');
 
@@ -26850,219 +26962,219 @@
   @Experimental
   void resolveLocalFileSystemUrl(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native;
 
-  @DomName('DOMWindow.DOMContentLoaded')
+  @DomName('DOMWindow.onDOMContentLoaded')
   @DocsEditable
   Stream<Event> get onContentLoaded => contentLoadedEvent.forTarget(this);
 
-  @DomName('DOMWindow.abort')
+  @DomName('DOMWindow.onabort')
   @DocsEditable
   Stream<Event> get onAbort => Element.abortEvent.forTarget(this);
 
-  @DomName('DOMWindow.beforeunload')
+  @DomName('DOMWindow.onbeforeunload')
   @DocsEditable
   Stream<Event> get onBeforeUnload => beforeUnloadEvent.forTarget(this);
 
-  @DomName('DOMWindow.blur')
+  @DomName('DOMWindow.onblur')
   @DocsEditable
   Stream<Event> get onBlur => Element.blurEvent.forTarget(this);
 
-  @DomName('DOMWindow.change')
+  @DomName('DOMWindow.onchange')
   @DocsEditable
   Stream<Event> get onChange => Element.changeEvent.forTarget(this);
 
-  @DomName('DOMWindow.click')
+  @DomName('DOMWindow.onclick')
   @DocsEditable
   Stream<MouseEvent> get onClick => Element.clickEvent.forTarget(this);
 
-  @DomName('DOMWindow.contextmenu')
+  @DomName('DOMWindow.oncontextmenu')
   @DocsEditable
   Stream<MouseEvent> get onContextMenu => Element.contextMenuEvent.forTarget(this);
 
-  @DomName('DOMWindow.dblclick')
+  @DomName('DOMWindow.ondblclick')
   @DocsEditable
   Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);
 
-  @DomName('DOMWindow.devicemotion')
+  @DomName('DOMWindow.ondevicemotion')
   @DocsEditable
   Stream<DeviceMotionEvent> get onDeviceMotion => deviceMotionEvent.forTarget(this);
 
-  @DomName('DOMWindow.deviceorientation')
+  @DomName('DOMWindow.ondeviceorientation')
   @DocsEditable
   Stream<DeviceOrientationEvent> get onDeviceOrientation => deviceOrientationEvent.forTarget(this);
 
-  @DomName('DOMWindow.drag')
+  @DomName('DOMWindow.ondrag')
   @DocsEditable
   Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);
 
-  @DomName('DOMWindow.dragend')
+  @DomName('DOMWindow.ondragend')
   @DocsEditable
   Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);
 
-  @DomName('DOMWindow.dragenter')
+  @DomName('DOMWindow.ondragenter')
   @DocsEditable
   Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);
 
-  @DomName('DOMWindow.dragleave')
+  @DomName('DOMWindow.ondragleave')
   @DocsEditable
   Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);
 
-  @DomName('DOMWindow.dragover')
+  @DomName('DOMWindow.ondragover')
   @DocsEditable
   Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);
 
-  @DomName('DOMWindow.dragstart')
+  @DomName('DOMWindow.ondragstart')
   @DocsEditable
   Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);
 
-  @DomName('DOMWindow.drop')
+  @DomName('DOMWindow.ondrop')
   @DocsEditable
   Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);
 
-  @DomName('DOMWindow.error')
+  @DomName('DOMWindow.onerror')
   @DocsEditable
   Stream<Event> get onError => Element.errorEvent.forTarget(this);
 
-  @DomName('DOMWindow.focus')
+  @DomName('DOMWindow.onfocus')
   @DocsEditable
   Stream<Event> get onFocus => Element.focusEvent.forTarget(this);
 
-  @DomName('DOMWindow.hashchange')
+  @DomName('DOMWindow.onhashchange')
   @DocsEditable
   Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);
 
-  @DomName('DOMWindow.input')
+  @DomName('DOMWindow.oninput')
   @DocsEditable
   Stream<Event> get onInput => Element.inputEvent.forTarget(this);
 
-  @DomName('DOMWindow.invalid')
+  @DomName('DOMWindow.oninvalid')
   @DocsEditable
   Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);
 
-  @DomName('DOMWindow.keydown')
+  @DomName('DOMWindow.onkeydown')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);
 
-  @DomName('DOMWindow.keypress')
+  @DomName('DOMWindow.onkeypress')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);
 
-  @DomName('DOMWindow.keyup')
+  @DomName('DOMWindow.onkeyup')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);
 
-  @DomName('DOMWindow.load')
+  @DomName('DOMWindow.onload')
   @DocsEditable
   Stream<Event> get onLoad => Element.loadEvent.forTarget(this);
 
-  @DomName('DOMWindow.message')
+  @DomName('DOMWindow.onmessage')
   @DocsEditable
   Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
 
-  @DomName('DOMWindow.mousedown')
+  @DomName('DOMWindow.onmousedown')
   @DocsEditable
   Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);
 
-  @DomName('DOMWindow.mousemove')
+  @DomName('DOMWindow.onmousemove')
   @DocsEditable
   Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);
 
-  @DomName('DOMWindow.mouseout')
+  @DomName('DOMWindow.onmouseout')
   @DocsEditable
   Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);
 
-  @DomName('DOMWindow.mouseover')
+  @DomName('DOMWindow.onmouseover')
   @DocsEditable
   Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);
 
-  @DomName('DOMWindow.mouseup')
+  @DomName('DOMWindow.onmouseup')
   @DocsEditable
   Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);
 
-  @DomName('DOMWindow.mousewheel')
+  @DomName('DOMWindow.onmousewheel')
   @DocsEditable
   Stream<WheelEvent> get onMouseWheel => Element.mouseWheelEvent.forTarget(this);
 
-  @DomName('DOMWindow.offline')
+  @DomName('DOMWindow.onoffline')
   @DocsEditable
   Stream<Event> get onOffline => offlineEvent.forTarget(this);
 
-  @DomName('DOMWindow.online')
+  @DomName('DOMWindow.ononline')
   @DocsEditable
   Stream<Event> get onOnline => onlineEvent.forTarget(this);
 
-  @DomName('DOMWindow.pagehide')
+  @DomName('DOMWindow.onpagehide')
   @DocsEditable
   Stream<Event> get onPageHide => pageHideEvent.forTarget(this);
 
-  @DomName('DOMWindow.pageshow')
+  @DomName('DOMWindow.onpageshow')
   @DocsEditable
   Stream<Event> get onPageShow => pageShowEvent.forTarget(this);
 
-  @DomName('DOMWindow.popstate')
+  @DomName('DOMWindow.onpopstate')
   @DocsEditable
   Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);
 
-  @DomName('DOMWindow.reset')
+  @DomName('DOMWindow.onreset')
   @DocsEditable
   Stream<Event> get onReset => Element.resetEvent.forTarget(this);
 
-  @DomName('DOMWindow.resize')
+  @DomName('DOMWindow.onresize')
   @DocsEditable
   Stream<Event> get onResize => resizeEvent.forTarget(this);
 
-  @DomName('DOMWindow.scroll')
+  @DomName('DOMWindow.onscroll')
   @DocsEditable
   Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);
 
-  @DomName('DOMWindow.search')
+  @DomName('DOMWindow.onsearch')
   @DocsEditable
   Stream<Event> get onSearch => Element.searchEvent.forTarget(this);
 
-  @DomName('DOMWindow.select')
+  @DomName('DOMWindow.onselect')
   @DocsEditable
   Stream<Event> get onSelect => Element.selectEvent.forTarget(this);
 
-  @DomName('DOMWindow.storage')
+  @DomName('DOMWindow.onstorage')
   @DocsEditable
   Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);
 
-  @DomName('DOMWindow.submit')
+  @DomName('DOMWindow.onsubmit')
   @DocsEditable
   Stream<Event> get onSubmit => Element.submitEvent.forTarget(this);
 
-  @DomName('DOMWindow.touchcancel')
+  @DomName('DOMWindow.ontouchcancel')
   @DocsEditable
   Stream<TouchEvent> get onTouchCancel => Element.touchCancelEvent.forTarget(this);
 
-  @DomName('DOMWindow.touchend')
+  @DomName('DOMWindow.ontouchend')
   @DocsEditable
   Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);
 
-  @DomName('DOMWindow.touchmove')
+  @DomName('DOMWindow.ontouchmove')
   @DocsEditable
   Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);
 
-  @DomName('DOMWindow.touchstart')
+  @DomName('DOMWindow.ontouchstart')
   @DocsEditable
   Stream<TouchEvent> get onTouchStart => Element.touchStartEvent.forTarget(this);
 
-  @DomName('DOMWindow.unload')
+  @DomName('DOMWindow.onunload')
   @DocsEditable
   Stream<Event> get onUnload => unloadEvent.forTarget(this);
 
-  @DomName('DOMWindow.webkitAnimationEnd')
+  @DomName('DOMWindow.onwebkitAnimationEnd')
   @DocsEditable
   Stream<AnimationEvent> get onAnimationEnd => animationEndEvent.forTarget(this);
 
-  @DomName('DOMWindow.webkitAnimationIteration')
+  @DomName('DOMWindow.onwebkitAnimationIteration')
   @DocsEditable
   Stream<AnimationEvent> get onAnimationIteration => animationIterationEvent.forTarget(this);
 
-  @DomName('DOMWindow.webkitAnimationStart')
+  @DomName('DOMWindow.onwebkitAnimationStart')
   @DocsEditable
   Stream<AnimationEvent> get onAnimationStart => animationStartEvent.forTarget(this);
 
-  @DomName('DOMWindow.webkitTransitionEnd')
+  @DomName('DOMWindow.onwebkitTransitionEnd')
   @DocsEditable
   Stream<TransitionEvent> get onTransitionEnd => Element.transitionEndEvent.forTarget(this);
 
@@ -27305,7 +27417,7 @@
 @DomName('Worker')
 class Worker extends AbstractWorker native "*Worker" {
 
-  @DomName('Worker.message')
+  @DomName('Worker.messageEvent')
   @DocsEditable
   static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
 
@@ -27345,7 +27457,7 @@
   @DocsEditable
   void terminate() native;
 
-  @DomName('Worker.message')
+  @DomName('Worker.onmessage')
   @DocsEditable
   Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
 }
@@ -27367,7 +27479,7 @@
 @DomName('WorkerContext')
 class WorkerContext extends EventTarget native "*WorkerContext" {
 
-  @DomName('WorkerContext.error')
+  @DomName('WorkerContext.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
@@ -27477,7 +27589,7 @@
   @Experimental
   void resolveLocalFileSystemUrl(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native;
 
-  @DomName('WorkerContext.error')
+  @DomName('WorkerContext.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
@@ -27810,24 +27922,6 @@
 
 
 @DocsEditable
-@DomName('HTMLAppletElement')
-class _AppletElement extends Element native "*HTMLAppletElement" {
-}
-// 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.
-
-
-@DocsEditable
-@DomName('HTMLBaseFontElement')
-class _BaseFontElement extends Element native "*HTMLBaseFontElement" {
-}
-// 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.
-
-
-@DocsEditable
 @DomName('ClientRectList')
 class _ClientRectList implements JavaScriptIndexingBehavior, List<ClientRect> native "*ClientRectList" {
 
@@ -27864,7 +27958,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(ClientRect element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(ClientRect element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -28061,7 +28155,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(CssRule element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(CssRule element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -28258,7 +28352,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(CssValue element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(CssValue element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -28419,15 +28513,6 @@
 
 
 @DocsEditable
-@DomName('HTMLDirectoryElement')
-class _DirectoryElement extends Element native "*HTMLDirectoryElement" {
-}
-// 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.
-
-
-@DocsEditable
 @DomName('EntryArray')
 class _EntryArray implements JavaScriptIndexingBehavior, List<Entry> native "*EntryArray" {
 
@@ -28464,7 +28549,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Entry element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Entry element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -28661,7 +28746,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(EntrySync element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(EntrySync element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -28822,85 +28907,6 @@
 
 
 @DocsEditable
-@DomName('HTMLFontElement')
-class _FontElement extends Element native "*HTMLFontElement" {
-}
-// 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.
-
-
-@DocsEditable
-@DomName('HTMLFrameElement')
-class _FrameElement extends Element native "*HTMLFrameElement" {
-}
-// 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.
-
-
-@DocsEditable
-@DomName('HTMLFrameSetElement')
-class _FrameSetElement extends Element native "*HTMLFrameSetElement" {
-
-  @DocsEditable
-  @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
-  @deprecated
-  _FrameSetElementEvents get on =>
-    new _FrameSetElementEvents(this);
-}
-
-@DocsEditable
-@deprecated
-class _FrameSetElementEvents extends ElementEvents {
-  @DocsEditable
-  _FrameSetElementEvents(EventTarget _ptr) : super(_ptr);
-
-  @DocsEditable
-  EventListenerList get beforeUnload => this['beforeunload'];
-
-  @DocsEditable
-  EventListenerList get blur => this['blur'];
-
-  @DocsEditable
-  EventListenerList get error => this['error'];
-
-  @DocsEditable
-  EventListenerList get focus => this['focus'];
-
-  @DocsEditable
-  EventListenerList get hashChange => this['hashchange'];
-
-  @DocsEditable
-  EventListenerList get load => this['load'];
-
-  @DocsEditable
-  EventListenerList get message => this['message'];
-
-  @DocsEditable
-  EventListenerList get offline => this['offline'];
-
-  @DocsEditable
-  EventListenerList get online => this['online'];
-
-  @DocsEditable
-  EventListenerList get popState => this['popstate'];
-
-  @DocsEditable
-  EventListenerList get resize => this['resize'];
-
-  @DocsEditable
-  EventListenerList get storage => this['storage'];
-
-  @DocsEditable
-  EventListenerList get unload => this['unload'];
-}
-// 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.
-
-
-@DocsEditable
 @DomName('GamepadList')
 class _GamepadList implements JavaScriptIndexingBehavior, List<Gamepad> native "*GamepadList" {
 
@@ -28937,7 +28943,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Gamepad element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Gamepad element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -29098,8 +29104,114 @@
 
 
 @DocsEditable
+@DomName('HTMLAppletElement')
+class _HTMLAppletElement extends Element native "*HTMLAppletElement" {
+}
+// 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.
+
+
+@DocsEditable
+@DomName('HTMLBaseFontElement')
+class _HTMLBaseFontElement extends Element native "*HTMLBaseFontElement" {
+}
+// 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.
+
+
+@DocsEditable
+@DomName('HTMLDirectoryElement')
+class _HTMLDirectoryElement extends Element native "*HTMLDirectoryElement" {
+}
+// 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.
+
+
+@DocsEditable
+@DomName('HTMLFontElement')
+class _HTMLFontElement extends Element native "*HTMLFontElement" {
+}
+// 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.
+
+
+@DocsEditable
+@DomName('HTMLFrameElement')
+class _HTMLFrameElement extends Element native "*HTMLFrameElement" {
+}
+// 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.
+
+
+@DocsEditable
+@DomName('HTMLFrameSetElement')
+class _HTMLFrameSetElement extends Element native "*HTMLFrameSetElement" {
+
+  @DocsEditable
+  @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
+  @deprecated
+  _HTMLFrameSetElementEvents get on =>
+    new _HTMLFrameSetElementEvents(this);
+}
+
+@DocsEditable
+@deprecated
+class _HTMLFrameSetElementEvents extends ElementEvents {
+  @DocsEditable
+  _HTMLFrameSetElementEvents(EventTarget _ptr) : super(_ptr);
+
+  @DocsEditable
+  EventListenerList get beforeUnload => this['beforeunload'];
+
+  @DocsEditable
+  EventListenerList get blur => this['blur'];
+
+  @DocsEditable
+  EventListenerList get error => this['error'];
+
+  @DocsEditable
+  EventListenerList get focus => this['focus'];
+
+  @DocsEditable
+  EventListenerList get hashChange => this['hashchange'];
+
+  @DocsEditable
+  EventListenerList get load => this['load'];
+
+  @DocsEditable
+  EventListenerList get message => this['message'];
+
+  @DocsEditable
+  EventListenerList get offline => this['offline'];
+
+  @DocsEditable
+  EventListenerList get online => this['online'];
+
+  @DocsEditable
+  EventListenerList get popState => this['popstate'];
+
+  @DocsEditable
+  EventListenerList get resize => this['resize'];
+
+  @DocsEditable
+  EventListenerList get storage => this['storage'];
+
+  @DocsEditable
+  EventListenerList get unload => this['unload'];
+}
+// 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.
+
+
+@DocsEditable
 @DomName('HTMLMarqueeElement')
-class _MarqueeElement extends Element native "*HTMLMarqueeElement" {
+class _HTMLMarqueeElement extends Element native "*HTMLMarqueeElement" {
 }
 // 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
@@ -29143,7 +29255,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(MediaStream element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(MediaStream element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -29340,7 +29452,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(SpeechInputResult element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(SpeechInputResult element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -29537,7 +29649,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(SpeechRecognitionResult element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(SpeechRecognitionResult element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -29734,7 +29846,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(StyleSheet element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(StyleSheet element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 41f2758..8884e11 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -77,7 +77,7 @@
 class AbstractWorker extends EventTarget {
   AbstractWorker.internal() : super.internal();
 
-  @DomName('AbstractWorker.error')
+  @DomName('AbstractWorker.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
@@ -99,7 +99,7 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "AbstractWorker_removeEventListener_Callback";
 
-  @DomName('AbstractWorker.error')
+  @DomName('AbstractWorker.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
@@ -301,35 +301,35 @@
 class ApplicationCache extends EventTarget {
   ApplicationCache.internal() : super.internal();
 
-  @DomName('DOMApplicationCache.cached')
+  @DomName('DOMApplicationCache.cachedEvent')
   @DocsEditable
   static const EventStreamProvider<Event> cachedEvent = const EventStreamProvider<Event>('cached');
 
-  @DomName('DOMApplicationCache.checking')
+  @DomName('DOMApplicationCache.checkingEvent')
   @DocsEditable
   static const EventStreamProvider<Event> checkingEvent = const EventStreamProvider<Event>('checking');
 
-  @DomName('DOMApplicationCache.downloading')
+  @DomName('DOMApplicationCache.downloadingEvent')
   @DocsEditable
   static const EventStreamProvider<Event> downloadingEvent = const EventStreamProvider<Event>('downloading');
 
-  @DomName('DOMApplicationCache.error')
+  @DomName('DOMApplicationCache.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('DOMApplicationCache.noupdate')
+  @DomName('DOMApplicationCache.noupdateEvent')
   @DocsEditable
   static const EventStreamProvider<Event> noUpdateEvent = const EventStreamProvider<Event>('noupdate');
 
-  @DomName('DOMApplicationCache.obsolete')
+  @DomName('DOMApplicationCache.obsoleteEvent')
   @DocsEditable
   static const EventStreamProvider<Event> obsoleteEvent = const EventStreamProvider<Event>('obsolete');
 
-  @DomName('DOMApplicationCache.progress')
+  @DomName('DOMApplicationCache.progressEvent')
   @DocsEditable
   static const EventStreamProvider<Event> progressEvent = const EventStreamProvider<Event>('progress');
 
-  @DomName('DOMApplicationCache.updateready')
+  @DomName('DOMApplicationCache.updatereadyEvent')
   @DocsEditable
   static const EventStreamProvider<Event> updateReadyEvent = const EventStreamProvider<Event>('updateready');
 
@@ -382,35 +382,35 @@
   @DocsEditable
   void update() native "DOMApplicationCache_update_Callback";
 
-  @DomName('DOMApplicationCache.cached')
+  @DomName('DOMApplicationCache.oncached')
   @DocsEditable
   Stream<Event> get onCached => cachedEvent.forTarget(this);
 
-  @DomName('DOMApplicationCache.checking')
+  @DomName('DOMApplicationCache.onchecking')
   @DocsEditable
   Stream<Event> get onChecking => checkingEvent.forTarget(this);
 
-  @DomName('DOMApplicationCache.downloading')
+  @DomName('DOMApplicationCache.ondownloading')
   @DocsEditable
   Stream<Event> get onDownloading => downloadingEvent.forTarget(this);
 
-  @DomName('DOMApplicationCache.error')
+  @DomName('DOMApplicationCache.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('DOMApplicationCache.noupdate')
+  @DomName('DOMApplicationCache.onnoupdate')
   @DocsEditable
   Stream<Event> get onNoUpdate => noUpdateEvent.forTarget(this);
 
-  @DomName('DOMApplicationCache.obsolete')
+  @DomName('DOMApplicationCache.onobsolete')
   @DocsEditable
   Stream<Event> get onObsolete => obsoleteEvent.forTarget(this);
 
-  @DomName('DOMApplicationCache.progress')
+  @DomName('DOMApplicationCache.onprogress')
   @DocsEditable
   Stream<Event> get onProgress => progressEvent.forTarget(this);
 
-  @DomName('DOMApplicationCache.updateready')
+  @DomName('DOMApplicationCache.onupdateready')
   @DocsEditable
   Stream<Event> get onUpdateReady => updateReadyEvent.forTarget(this);
 
@@ -454,6 +454,16 @@
 
 
 @DocsEditable
+/**
+ * DOM Area Element, which links regions of an image map with a hyperlink.
+ *
+ * The element can also define an uninteractive region of the map.
+ *
+ * See also:
+ *
+ * * [<area>](https://developer.mozilla.org/en-US/docs/HTML/Element/area)
+ * on MDN.
+ */
 @DomName('HTMLAreaElement')
 class AreaElement extends _Element_Merged {
   AreaElement.internal() : super.internal();
@@ -725,19 +735,19 @@
 class BatteryManager extends EventTarget {
   BatteryManager.internal() : super.internal();
 
-  @DomName('BatteryManager.chargingchange')
+  @DomName('BatteryManager.chargingchangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> chargingChangeEvent = const EventStreamProvider<Event>('chargingchange');
 
-  @DomName('BatteryManager.chargingtimechange')
+  @DomName('BatteryManager.chargingtimechangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> chargingTimeChangeEvent = const EventStreamProvider<Event>('chargingtimechange');
 
-  @DomName('BatteryManager.dischargingtimechange')
+  @DomName('BatteryManager.dischargingtimechangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> dischargingTimeChangeEvent = const EventStreamProvider<Event>('dischargingtimechange');
 
-  @DomName('BatteryManager.levelchange')
+  @DomName('BatteryManager.levelchangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> levelChangeEvent = const EventStreamProvider<Event>('levelchange');
 
@@ -775,19 +785,19 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "BatteryManager_removeEventListener_Callback";
 
-  @DomName('BatteryManager.chargingchange')
+  @DomName('BatteryManager.onchargingchange')
   @DocsEditable
   Stream<Event> get onChargingChange => chargingChangeEvent.forTarget(this);
 
-  @DomName('BatteryManager.chargingtimechange')
+  @DomName('BatteryManager.onchargingtimechange')
   @DocsEditable
   Stream<Event> get onChargingTimeChange => chargingTimeChangeEvent.forTarget(this);
 
-  @DomName('BatteryManager.dischargingtimechange')
+  @DomName('BatteryManager.ondischargingtimechange')
   @DocsEditable
   Stream<Event> get onDischargingTimeChange => dischargingTimeChangeEvent.forTarget(this);
 
-  @DomName('BatteryManager.levelchange')
+  @DomName('BatteryManager.onlevelchange')
   @DocsEditable
   Stream<Event> get onLevelChange => levelChangeEvent.forTarget(this);
 
@@ -892,55 +902,55 @@
 class BodyElement extends _Element_Merged {
   BodyElement.internal() : super.internal();
 
-  @DomName('HTMLBodyElement.beforeunload')
+  @DomName('HTMLBodyElement.beforeunloadEvent')
   @DocsEditable
   static const EventStreamProvider<Event> beforeUnloadEvent = const EventStreamProvider<Event>('beforeunload');
 
-  @DomName('HTMLBodyElement.blur')
+  @DomName('HTMLBodyElement.blurEvent')
   @DocsEditable
   static const EventStreamProvider<Event> blurEvent = const EventStreamProvider<Event>('blur');
 
-  @DomName('HTMLBodyElement.error')
+  @DomName('HTMLBodyElement.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('HTMLBodyElement.focus')
+  @DomName('HTMLBodyElement.focusEvent')
   @DocsEditable
   static const EventStreamProvider<Event> focusEvent = const EventStreamProvider<Event>('focus');
 
-  @DomName('HTMLBodyElement.hashchange')
+  @DomName('HTMLBodyElement.hashchangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> hashChangeEvent = const EventStreamProvider<Event>('hashchange');
 
-  @DomName('HTMLBodyElement.load')
+  @DomName('HTMLBodyElement.loadEvent')
   @DocsEditable
   static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');
 
-  @DomName('HTMLBodyElement.message')
+  @DomName('HTMLBodyElement.messageEvent')
   @DocsEditable
   static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
 
-  @DomName('HTMLBodyElement.offline')
+  @DomName('HTMLBodyElement.offlineEvent')
   @DocsEditable
   static const EventStreamProvider<Event> offlineEvent = const EventStreamProvider<Event>('offline');
 
-  @DomName('HTMLBodyElement.online')
+  @DomName('HTMLBodyElement.onlineEvent')
   @DocsEditable
   static const EventStreamProvider<Event> onlineEvent = const EventStreamProvider<Event>('online');
 
-  @DomName('HTMLBodyElement.popstate')
+  @DomName('HTMLBodyElement.popstateEvent')
   @DocsEditable
   static const EventStreamProvider<PopStateEvent> popStateEvent = const EventStreamProvider<PopStateEvent>('popstate');
 
-  @DomName('HTMLBodyElement.resize')
+  @DomName('HTMLBodyElement.resizeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');
 
-  @DomName('HTMLBodyElement.storage')
+  @DomName('HTMLBodyElement.storageEvent')
   @DocsEditable
   static const EventStreamProvider<StorageEvent> storageEvent = const EventStreamProvider<StorageEvent>('storage');
 
-  @DomName('HTMLBodyElement.unload')
+  @DomName('HTMLBodyElement.unloadEvent')
   @DocsEditable
   static const EventStreamProvider<Event> unloadEvent = const EventStreamProvider<Event>('unload');
 
@@ -954,55 +964,55 @@
   BodyElementEvents get on =>
     new BodyElementEvents(this);
 
-  @DomName('HTMLBodyElement.beforeunload')
+  @DomName('HTMLBodyElement.onbeforeunload')
   @DocsEditable
   Stream<Event> get onBeforeUnload => beforeUnloadEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.blur')
+  @DomName('HTMLBodyElement.onblur')
   @DocsEditable
   Stream<Event> get onBlur => blurEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.error')
+  @DomName('HTMLBodyElement.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.focus')
+  @DomName('HTMLBodyElement.onfocus')
   @DocsEditable
   Stream<Event> get onFocus => focusEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.hashchange')
+  @DomName('HTMLBodyElement.onhashchange')
   @DocsEditable
   Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.load')
+  @DomName('HTMLBodyElement.onload')
   @DocsEditable
   Stream<Event> get onLoad => loadEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.message')
+  @DomName('HTMLBodyElement.onmessage')
   @DocsEditable
   Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.offline')
+  @DomName('HTMLBodyElement.onoffline')
   @DocsEditable
   Stream<Event> get onOffline => offlineEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.online')
+  @DomName('HTMLBodyElement.ononline')
   @DocsEditable
   Stream<Event> get onOnline => onlineEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.popstate')
+  @DomName('HTMLBodyElement.onpopstate')
   @DocsEditable
   Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.resize')
+  @DomName('HTMLBodyElement.onresize')
   @DocsEditable
   Stream<Event> get onResize => resizeEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.storage')
+  @DomName('HTMLBodyElement.onstorage')
   @DocsEditable
   Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);
 
-  @DomName('HTMLBodyElement.unload')
+  @DomName('HTMLBodyElement.onunload')
   @DocsEditable
   Stream<Event> get onUnload => unloadEvent.forTarget(this);
 
@@ -6903,7 +6913,7 @@
 class DedicatedWorkerContext extends WorkerContext {
   DedicatedWorkerContext.internal() : super.internal();
 
-  @DomName('DedicatedWorkerContext.message')
+  @DomName('DedicatedWorkerContext.messageEvent')
   @DocsEditable
   static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
 
@@ -6917,7 +6927,7 @@
   @DocsEditable
   void postMessage(Object message, [List messagePorts]) native "DedicatedWorkerContext_postMessage_Callback";
 
-  @DomName('DedicatedWorkerContext.message')
+  @DomName('DedicatedWorkerContext.onmessage')
   @DocsEditable
   Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
 
@@ -7170,19 +7180,19 @@
 
   Document.internal() : super.internal();
 
-  @DomName('Document.readystatechange')
+  @DomName('Document.readystatechangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> readyStateChangeEvent = const EventStreamProvider<Event>('readystatechange');
 
-  @DomName('Document.selectionchange')
+  @DomName('Document.selectionchangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> selectionChangeEvent = const EventStreamProvider<Event>('selectionchange');
 
-  @DomName('Document.webkitpointerlockchange')
+  @DomName('Document.webkitpointerlockchangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> pointerLockChangeEvent = const EventStreamProvider<Event>('webkitpointerlockchange');
 
-  @DomName('Document.webkitpointerlockerror')
+  @DomName('Document.webkitpointerlockerrorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> pointerLockErrorEvent = const EventStreamProvider<Event>('webkitpointerlockerror');
 
@@ -7427,199 +7437,199 @@
   @DocsEditable
   void $dom_webkitExitPointerLock() native "Document_webkitExitPointerLock_Callback";
 
-  @DomName('Document.abort')
+  @DomName('Document.onabort')
   @DocsEditable
   Stream<Event> get onAbort => Element.abortEvent.forTarget(this);
 
-  @DomName('Document.beforecopy')
+  @DomName('Document.onbeforecopy')
   @DocsEditable
   Stream<Event> get onBeforeCopy => Element.beforeCopyEvent.forTarget(this);
 
-  @DomName('Document.beforecut')
+  @DomName('Document.onbeforecut')
   @DocsEditable
   Stream<Event> get onBeforeCut => Element.beforeCutEvent.forTarget(this);
 
-  @DomName('Document.beforepaste')
+  @DomName('Document.onbeforepaste')
   @DocsEditable
   Stream<Event> get onBeforePaste => Element.beforePasteEvent.forTarget(this);
 
-  @DomName('Document.blur')
+  @DomName('Document.onblur')
   @DocsEditable
   Stream<Event> get onBlur => Element.blurEvent.forTarget(this);
 
-  @DomName('Document.change')
+  @DomName('Document.onchange')
   @DocsEditable
   Stream<Event> get onChange => Element.changeEvent.forTarget(this);
 
-  @DomName('Document.click')
+  @DomName('Document.onclick')
   @DocsEditable
   Stream<MouseEvent> get onClick => Element.clickEvent.forTarget(this);
 
-  @DomName('Document.contextmenu')
+  @DomName('Document.oncontextmenu')
   @DocsEditable
   Stream<MouseEvent> get onContextMenu => Element.contextMenuEvent.forTarget(this);
 
-  @DomName('Document.copy')
+  @DomName('Document.oncopy')
   @DocsEditable
   Stream<Event> get onCopy => Element.copyEvent.forTarget(this);
 
-  @DomName('Document.cut')
+  @DomName('Document.oncut')
   @DocsEditable
   Stream<Event> get onCut => Element.cutEvent.forTarget(this);
 
-  @DomName('Document.dblclick')
+  @DomName('Document.ondblclick')
   @DocsEditable
   Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);
 
-  @DomName('Document.drag')
+  @DomName('Document.ondrag')
   @DocsEditable
   Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);
 
-  @DomName('Document.dragend')
+  @DomName('Document.ondragend')
   @DocsEditable
   Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);
 
-  @DomName('Document.dragenter')
+  @DomName('Document.ondragenter')
   @DocsEditable
   Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);
 
-  @DomName('Document.dragleave')
+  @DomName('Document.ondragleave')
   @DocsEditable
   Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);
 
-  @DomName('Document.dragover')
+  @DomName('Document.ondragover')
   @DocsEditable
   Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);
 
-  @DomName('Document.dragstart')
+  @DomName('Document.ondragstart')
   @DocsEditable
   Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);
 
-  @DomName('Document.drop')
+  @DomName('Document.ondrop')
   @DocsEditable
   Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);
 
-  @DomName('Document.error')
+  @DomName('Document.onerror')
   @DocsEditable
   Stream<Event> get onError => Element.errorEvent.forTarget(this);
 
-  @DomName('Document.focus')
+  @DomName('Document.onfocus')
   @DocsEditable
   Stream<Event> get onFocus => Element.focusEvent.forTarget(this);
 
-  @DomName('Document.input')
+  @DomName('Document.oninput')
   @DocsEditable
   Stream<Event> get onInput => Element.inputEvent.forTarget(this);
 
-  @DomName('Document.invalid')
+  @DomName('Document.oninvalid')
   @DocsEditable
   Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);
 
-  @DomName('Document.keydown')
+  @DomName('Document.onkeydown')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);
 
-  @DomName('Document.keypress')
+  @DomName('Document.onkeypress')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);
 
-  @DomName('Document.keyup')
+  @DomName('Document.onkeyup')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);
 
-  @DomName('Document.load')
+  @DomName('Document.onload')
   @DocsEditable
   Stream<Event> get onLoad => Element.loadEvent.forTarget(this);
 
-  @DomName('Document.mousedown')
+  @DomName('Document.onmousedown')
   @DocsEditable
   Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);
 
-  @DomName('Document.mousemove')
+  @DomName('Document.onmousemove')
   @DocsEditable
   Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);
 
-  @DomName('Document.mouseout')
+  @DomName('Document.onmouseout')
   @DocsEditable
   Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);
 
-  @DomName('Document.mouseover')
+  @DomName('Document.onmouseover')
   @DocsEditable
   Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);
 
-  @DomName('Document.mouseup')
+  @DomName('Document.onmouseup')
   @DocsEditable
   Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);
 
-  @DomName('Document.mousewheel')
+  @DomName('Document.onmousewheel')
   @DocsEditable
   Stream<WheelEvent> get onMouseWheel => Element.mouseWheelEvent.forTarget(this);
 
-  @DomName('Document.paste')
+  @DomName('Document.onpaste')
   @DocsEditable
   Stream<Event> get onPaste => Element.pasteEvent.forTarget(this);
 
-  @DomName('Document.readystatechange')
+  @DomName('Document.onreadystatechange')
   @DocsEditable
   Stream<Event> get onReadyStateChange => readyStateChangeEvent.forTarget(this);
 
-  @DomName('Document.reset')
+  @DomName('Document.onreset')
   @DocsEditable
   Stream<Event> get onReset => Element.resetEvent.forTarget(this);
 
-  @DomName('Document.scroll')
+  @DomName('Document.onscroll')
   @DocsEditable
   Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);
 
-  @DomName('Document.search')
+  @DomName('Document.onsearch')
   @DocsEditable
   Stream<Event> get onSearch => Element.searchEvent.forTarget(this);
 
-  @DomName('Document.select')
+  @DomName('Document.onselect')
   @DocsEditable
   Stream<Event> get onSelect => Element.selectEvent.forTarget(this);
 
-  @DomName('Document.selectionchange')
+  @DomName('Document.onselectionchange')
   @DocsEditable
   Stream<Event> get onSelectionChange => selectionChangeEvent.forTarget(this);
 
-  @DomName('Document.selectstart')
+  @DomName('Document.onselectstart')
   @DocsEditable
   Stream<Event> get onSelectStart => Element.selectStartEvent.forTarget(this);
 
-  @DomName('Document.submit')
+  @DomName('Document.onsubmit')
   @DocsEditable
   Stream<Event> get onSubmit => Element.submitEvent.forTarget(this);
 
-  @DomName('Document.touchcancel')
+  @DomName('Document.ontouchcancel')
   @DocsEditable
   Stream<TouchEvent> get onTouchCancel => Element.touchCancelEvent.forTarget(this);
 
-  @DomName('Document.touchend')
+  @DomName('Document.ontouchend')
   @DocsEditable
   Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);
 
-  @DomName('Document.touchmove')
+  @DomName('Document.ontouchmove')
   @DocsEditable
   Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);
 
-  @DomName('Document.touchstart')
+  @DomName('Document.ontouchstart')
   @DocsEditable
   Stream<TouchEvent> get onTouchStart => Element.touchStartEvent.forTarget(this);
 
-  @DomName('Document.webkitfullscreenchange')
+  @DomName('Document.onwebkitfullscreenchange')
   @DocsEditable
   Stream<Event> get onFullscreenChange => Element.fullscreenChangeEvent.forTarget(this);
 
-  @DomName('Document.webkitfullscreenerror')
+  @DomName('Document.onwebkitfullscreenerror')
   @DocsEditable
   Stream<Event> get onFullscreenError => Element.fullscreenErrorEvent.forTarget(this);
 
-  @DomName('Document.webkitpointerlockchange')
+  @DomName('Document.onwebkitpointerlockchange')
   @DocsEditable
   Stream<Event> get onPointerLockChange => pointerLockChangeEvent.forTarget(this);
 
-  @DomName('Document.webkitpointerlockerror')
+  @DomName('Document.onwebkitpointerlockerror')
   @DocsEditable
   Stream<Event> get onPointerLockError => pointerLockErrorEvent.forTarget(this);
 
@@ -7719,15 +7729,6 @@
   factory DocumentFragment.svg(String svgContent) =>
       _DocumentFragmentFactoryProvider.createDocumentFragment_svg(svgContent);
 
-  @deprecated
-  List<Element> get elements => this.children;
-
-  // TODO: The type of value should be Collection<Element>. See http://b/5392897
-  @deprecated
-  void set elements(value) {
-    this.children = value;
-  }
-
   List<Element> _children;
 
   List<Element> get children {
@@ -7769,14 +7770,27 @@
     this.nodes.addAll(nodes);
   }
 
+  /**
+   * Adds the specified element after the last child of this
+   * document fragment.
+   */
   void append(Element element) {
     this.children.add(element);
   }
 
+  /**
+   * Adds the specified text as a text node after the last child of this
+   * document fragment.
+   */
   void appendText(String text) {
     this.nodes.add(new Text(text));
   }
 
+
+  /**
+   * Parses the specified text as HTML and adds the resulting node after the
+   * last child of this document fragment.
+   */
   void appendHtml(String text) {
     this.nodes.add(new DocumentFragment.html(text));
   }
@@ -7980,7 +7994,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(DomMimeType element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(DomMimeType element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -8248,7 +8262,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(DomPlugin element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(DomPlugin element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -8634,7 +8648,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(String element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(String element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -8914,7 +8928,7 @@
   }
 
   Iterable map(f(Element element)) {
-    return IterableMixinWorkaround.map(this, f);
+    return IterableMixinWorkaround.mapList(this, f);
   }
 
   List mappedBy(f(Element element)) {
@@ -9131,7 +9145,7 @@
   }
 
   Iterable map(f(Element element)) {
-    return IterableMixinWorkaround.map(this, f);
+    return IterableMixinWorkaround.mapList(this, f);
   }
 
   List mappedBy(f(Element element)) {
@@ -9428,27 +9442,6 @@
   }
 
   /**
-   * Deprecated, use innerHtml instead.
-   */
-  @deprecated
-  String get innerHTML => this.innerHtml;
-  @deprecated
-  void set innerHTML(String value) {
-    this.innerHtml = value;
-  }
-
-  @deprecated
-  void set elements(Collection<Element> value) {
-    this.children = value;
-  }
-
-  /**
-   * Deprecated, use [children] instead.
-   */
-  @deprecated
-  List<Element> get elements => this.children;
-
-  /**
    * List of the direct children of this element.
    *
    * This collection can be used to add and remove elements from the document.
@@ -9635,195 +9628,195 @@
 
   Element.internal() : super.internal();
 
-  @DomName('Element.abort')
+  @DomName('Element.abortEvent')
   @DocsEditable
   static const EventStreamProvider<Event> abortEvent = const EventStreamProvider<Event>('abort');
 
-  @DomName('Element.beforecopy')
+  @DomName('Element.beforecopyEvent')
   @DocsEditable
   static const EventStreamProvider<Event> beforeCopyEvent = const EventStreamProvider<Event>('beforecopy');
 
-  @DomName('Element.beforecut')
+  @DomName('Element.beforecutEvent')
   @DocsEditable
   static const EventStreamProvider<Event> beforeCutEvent = const EventStreamProvider<Event>('beforecut');
 
-  @DomName('Element.beforepaste')
+  @DomName('Element.beforepasteEvent')
   @DocsEditable
   static const EventStreamProvider<Event> beforePasteEvent = const EventStreamProvider<Event>('beforepaste');
 
-  @DomName('Element.blur')
+  @DomName('Element.blurEvent')
   @DocsEditable
   static const EventStreamProvider<Event> blurEvent = const EventStreamProvider<Event>('blur');
 
-  @DomName('Element.change')
+  @DomName('Element.changeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');
 
-  @DomName('Element.click')
+  @DomName('Element.clickEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> clickEvent = const EventStreamProvider<MouseEvent>('click');
 
-  @DomName('Element.contextmenu')
+  @DomName('Element.contextmenuEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> contextMenuEvent = const EventStreamProvider<MouseEvent>('contextmenu');
 
-  @DomName('Element.copy')
+  @DomName('Element.copyEvent')
   @DocsEditable
   static const EventStreamProvider<Event> copyEvent = const EventStreamProvider<Event>('copy');
 
-  @DomName('Element.cut')
+  @DomName('Element.cutEvent')
   @DocsEditable
   static const EventStreamProvider<Event> cutEvent = const EventStreamProvider<Event>('cut');
 
-  @DomName('Element.dblclick')
+  @DomName('Element.dblclickEvent')
   @DocsEditable
   static const EventStreamProvider<Event> doubleClickEvent = const EventStreamProvider<Event>('dblclick');
 
-  @DomName('Element.drag')
+  @DomName('Element.dragEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragEvent = const EventStreamProvider<MouseEvent>('drag');
 
-  @DomName('Element.dragend')
+  @DomName('Element.dragendEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragEndEvent = const EventStreamProvider<MouseEvent>('dragend');
 
-  @DomName('Element.dragenter')
+  @DomName('Element.dragenterEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragEnterEvent = const EventStreamProvider<MouseEvent>('dragenter');
 
-  @DomName('Element.dragleave')
+  @DomName('Element.dragleaveEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragLeaveEvent = const EventStreamProvider<MouseEvent>('dragleave');
 
-  @DomName('Element.dragover')
+  @DomName('Element.dragoverEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragOverEvent = const EventStreamProvider<MouseEvent>('dragover');
 
-  @DomName('Element.dragstart')
+  @DomName('Element.dragstartEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragStartEvent = const EventStreamProvider<MouseEvent>('dragstart');
 
-  @DomName('Element.drop')
+  @DomName('Element.dropEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dropEvent = const EventStreamProvider<MouseEvent>('drop');
 
-  @DomName('Element.error')
+  @DomName('Element.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('Element.focus')
+  @DomName('Element.focusEvent')
   @DocsEditable
   static const EventStreamProvider<Event> focusEvent = const EventStreamProvider<Event>('focus');
 
-  @DomName('Element.input')
+  @DomName('Element.inputEvent')
   @DocsEditable
   static const EventStreamProvider<Event> inputEvent = const EventStreamProvider<Event>('input');
 
-  @DomName('Element.invalid')
+  @DomName('Element.invalidEvent')
   @DocsEditable
   static const EventStreamProvider<Event> invalidEvent = const EventStreamProvider<Event>('invalid');
 
-  @DomName('Element.keydown')
+  @DomName('Element.keydownEvent')
   @DocsEditable
   static const EventStreamProvider<KeyboardEvent> keyDownEvent = const EventStreamProvider<KeyboardEvent>('keydown');
 
-  @DomName('Element.keypress')
+  @DomName('Element.keypressEvent')
   @DocsEditable
   static const EventStreamProvider<KeyboardEvent> keyPressEvent = const EventStreamProvider<KeyboardEvent>('keypress');
 
-  @DomName('Element.keyup')
+  @DomName('Element.keyupEvent')
   @DocsEditable
   static const EventStreamProvider<KeyboardEvent> keyUpEvent = const EventStreamProvider<KeyboardEvent>('keyup');
 
-  @DomName('Element.load')
+  @DomName('Element.loadEvent')
   @DocsEditable
   static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');
 
-  @DomName('Element.mousedown')
+  @DomName('Element.mousedownEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> mouseDownEvent = const EventStreamProvider<MouseEvent>('mousedown');
 
-  @DomName('Element.mousemove')
+  @DomName('Element.mousemoveEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> mouseMoveEvent = const EventStreamProvider<MouseEvent>('mousemove');
 
-  @DomName('Element.mouseout')
+  @DomName('Element.mouseoutEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> mouseOutEvent = const EventStreamProvider<MouseEvent>('mouseout');
 
-  @DomName('Element.mouseover')
+  @DomName('Element.mouseoverEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> mouseOverEvent = const EventStreamProvider<MouseEvent>('mouseover');
 
-  @DomName('Element.mouseup')
+  @DomName('Element.mouseupEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> mouseUpEvent = const EventStreamProvider<MouseEvent>('mouseup');
 
-  @DomName('Element.mousewheel')
+  @DomName('Element.mousewheelEvent')
   @DocsEditable
   static const EventStreamProvider<WheelEvent> mouseWheelEvent = const EventStreamProvider<WheelEvent>('mousewheel');
 
-  @DomName('Element.paste')
+  @DomName('Element.pasteEvent')
   @DocsEditable
   static const EventStreamProvider<Event> pasteEvent = const EventStreamProvider<Event>('paste');
 
-  @DomName('Element.reset')
+  @DomName('Element.resetEvent')
   @DocsEditable
   static const EventStreamProvider<Event> resetEvent = const EventStreamProvider<Event>('reset');
 
-  @DomName('Element.scroll')
+  @DomName('Element.scrollEvent')
   @DocsEditable
   static const EventStreamProvider<Event> scrollEvent = const EventStreamProvider<Event>('scroll');
 
-  @DomName('Element.search')
+  @DomName('Element.searchEvent')
   @DocsEditable
   static const EventStreamProvider<Event> searchEvent = const EventStreamProvider<Event>('search');
 
-  @DomName('Element.select')
+  @DomName('Element.selectEvent')
   @DocsEditable
   static const EventStreamProvider<Event> selectEvent = const EventStreamProvider<Event>('select');
 
-  @DomName('Element.selectstart')
+  @DomName('Element.selectstartEvent')
   @DocsEditable
   static const EventStreamProvider<Event> selectStartEvent = const EventStreamProvider<Event>('selectstart');
 
-  @DomName('Element.submit')
+  @DomName('Element.submitEvent')
   @DocsEditable
   static const EventStreamProvider<Event> submitEvent = const EventStreamProvider<Event>('submit');
 
-  @DomName('Element.touchcancel')
+  @DomName('Element.touchcancelEvent')
   @DocsEditable
   static const EventStreamProvider<TouchEvent> touchCancelEvent = const EventStreamProvider<TouchEvent>('touchcancel');
 
-  @DomName('Element.touchend')
+  @DomName('Element.touchendEvent')
   @DocsEditable
   static const EventStreamProvider<TouchEvent> touchEndEvent = const EventStreamProvider<TouchEvent>('touchend');
 
-  @DomName('Element.touchenter')
+  @DomName('Element.touchenterEvent')
   @DocsEditable
   static const EventStreamProvider<TouchEvent> touchEnterEvent = const EventStreamProvider<TouchEvent>('touchenter');
 
-  @DomName('Element.touchleave')
+  @DomName('Element.touchleaveEvent')
   @DocsEditable
   static const EventStreamProvider<TouchEvent> touchLeaveEvent = const EventStreamProvider<TouchEvent>('touchleave');
 
-  @DomName('Element.touchmove')
+  @DomName('Element.touchmoveEvent')
   @DocsEditable
   static const EventStreamProvider<TouchEvent> touchMoveEvent = const EventStreamProvider<TouchEvent>('touchmove');
 
-  @DomName('Element.touchstart')
+  @DomName('Element.touchstartEvent')
   @DocsEditable
   static const EventStreamProvider<TouchEvent> touchStartEvent = const EventStreamProvider<TouchEvent>('touchstart');
 
-  @DomName('Element.webkitTransitionEnd')
+  @DomName('Element.webkitTransitionEndEvent')
   @DocsEditable
   static const EventStreamProvider<TransitionEvent> transitionEndEvent = const EventStreamProvider<TransitionEvent>('webkitTransitionEnd');
 
-  @DomName('Element.webkitfullscreenchange')
+  @DomName('Element.webkitfullscreenchangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> fullscreenChangeEvent = const EventStreamProvider<Event>('webkitfullscreenchange');
 
-  @DomName('Element.webkitfullscreenerror')
+  @DomName('Element.webkitfullscreenerrorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> fullscreenErrorEvent = const EventStreamProvider<Event>('webkitfullscreenerror');
 
@@ -10086,6 +10079,7 @@
 
   @DomName('Element.webkitMatchesSelector')
   @DocsEditable
+  @Experimental()
   bool matches(String selectors) native "Element_webkitMatchesSelector_Callback";
 
   @DomName('Element.webkitRequestFullScreen')
@@ -10100,195 +10094,195 @@
   @DocsEditable
   void webkitRequestPointerLock() native "Element_webkitRequestPointerLock_Callback";
 
-  @DomName('Element.abort')
+  @DomName('Element.onabort')
   @DocsEditable
   Stream<Event> get onAbort => abortEvent.forTarget(this);
 
-  @DomName('Element.beforecopy')
+  @DomName('Element.onbeforecopy')
   @DocsEditable
   Stream<Event> get onBeforeCopy => beforeCopyEvent.forTarget(this);
 
-  @DomName('Element.beforecut')
+  @DomName('Element.onbeforecut')
   @DocsEditable
   Stream<Event> get onBeforeCut => beforeCutEvent.forTarget(this);
 
-  @DomName('Element.beforepaste')
+  @DomName('Element.onbeforepaste')
   @DocsEditable
   Stream<Event> get onBeforePaste => beforePasteEvent.forTarget(this);
 
-  @DomName('Element.blur')
+  @DomName('Element.onblur')
   @DocsEditable
   Stream<Event> get onBlur => blurEvent.forTarget(this);
 
-  @DomName('Element.change')
+  @DomName('Element.onchange')
   @DocsEditable
   Stream<Event> get onChange => changeEvent.forTarget(this);
 
-  @DomName('Element.click')
+  @DomName('Element.onclick')
   @DocsEditable
   Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
 
-  @DomName('Element.contextmenu')
+  @DomName('Element.oncontextmenu')
   @DocsEditable
   Stream<MouseEvent> get onContextMenu => contextMenuEvent.forTarget(this);
 
-  @DomName('Element.copy')
+  @DomName('Element.oncopy')
   @DocsEditable
   Stream<Event> get onCopy => copyEvent.forTarget(this);
 
-  @DomName('Element.cut')
+  @DomName('Element.oncut')
   @DocsEditable
   Stream<Event> get onCut => cutEvent.forTarget(this);
 
-  @DomName('Element.dblclick')
+  @DomName('Element.ondblclick')
   @DocsEditable
   Stream<Event> get onDoubleClick => doubleClickEvent.forTarget(this);
 
-  @DomName('Element.drag')
+  @DomName('Element.ondrag')
   @DocsEditable
   Stream<MouseEvent> get onDrag => dragEvent.forTarget(this);
 
-  @DomName('Element.dragend')
+  @DomName('Element.ondragend')
   @DocsEditable
   Stream<MouseEvent> get onDragEnd => dragEndEvent.forTarget(this);
 
-  @DomName('Element.dragenter')
+  @DomName('Element.ondragenter')
   @DocsEditable
   Stream<MouseEvent> get onDragEnter => dragEnterEvent.forTarget(this);
 
-  @DomName('Element.dragleave')
+  @DomName('Element.ondragleave')
   @DocsEditable
   Stream<MouseEvent> get onDragLeave => dragLeaveEvent.forTarget(this);
 
-  @DomName('Element.dragover')
+  @DomName('Element.ondragover')
   @DocsEditable
   Stream<MouseEvent> get onDragOver => dragOverEvent.forTarget(this);
 
-  @DomName('Element.dragstart')
+  @DomName('Element.ondragstart')
   @DocsEditable
   Stream<MouseEvent> get onDragStart => dragStartEvent.forTarget(this);
 
-  @DomName('Element.drop')
+  @DomName('Element.ondrop')
   @DocsEditable
   Stream<MouseEvent> get onDrop => dropEvent.forTarget(this);
 
-  @DomName('Element.error')
+  @DomName('Element.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('Element.focus')
+  @DomName('Element.onfocus')
   @DocsEditable
   Stream<Event> get onFocus => focusEvent.forTarget(this);
 
-  @DomName('Element.input')
+  @DomName('Element.oninput')
   @DocsEditable
   Stream<Event> get onInput => inputEvent.forTarget(this);
 
-  @DomName('Element.invalid')
+  @DomName('Element.oninvalid')
   @DocsEditable
   Stream<Event> get onInvalid => invalidEvent.forTarget(this);
 
-  @DomName('Element.keydown')
+  @DomName('Element.onkeydown')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyDown => keyDownEvent.forTarget(this);
 
-  @DomName('Element.keypress')
+  @DomName('Element.onkeypress')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyPress => keyPressEvent.forTarget(this);
 
-  @DomName('Element.keyup')
+  @DomName('Element.onkeyup')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyUp => keyUpEvent.forTarget(this);
 
-  @DomName('Element.load')
+  @DomName('Element.onload')
   @DocsEditable
   Stream<Event> get onLoad => loadEvent.forTarget(this);
 
-  @DomName('Element.mousedown')
+  @DomName('Element.onmousedown')
   @DocsEditable
   Stream<MouseEvent> get onMouseDown => mouseDownEvent.forTarget(this);
 
-  @DomName('Element.mousemove')
+  @DomName('Element.onmousemove')
   @DocsEditable
   Stream<MouseEvent> get onMouseMove => mouseMoveEvent.forTarget(this);
 
-  @DomName('Element.mouseout')
+  @DomName('Element.onmouseout')
   @DocsEditable
   Stream<MouseEvent> get onMouseOut => mouseOutEvent.forTarget(this);
 
-  @DomName('Element.mouseover')
+  @DomName('Element.onmouseover')
   @DocsEditable
   Stream<MouseEvent> get onMouseOver => mouseOverEvent.forTarget(this);
 
-  @DomName('Element.mouseup')
+  @DomName('Element.onmouseup')
   @DocsEditable
   Stream<MouseEvent> get onMouseUp => mouseUpEvent.forTarget(this);
 
-  @DomName('Element.mousewheel')
+  @DomName('Element.onmousewheel')
   @DocsEditable
   Stream<WheelEvent> get onMouseWheel => mouseWheelEvent.forTarget(this);
 
-  @DomName('Element.paste')
+  @DomName('Element.onpaste')
   @DocsEditable
   Stream<Event> get onPaste => pasteEvent.forTarget(this);
 
-  @DomName('Element.reset')
+  @DomName('Element.onreset')
   @DocsEditable
   Stream<Event> get onReset => resetEvent.forTarget(this);
 
-  @DomName('Element.scroll')
+  @DomName('Element.onscroll')
   @DocsEditable
   Stream<Event> get onScroll => scrollEvent.forTarget(this);
 
-  @DomName('Element.search')
+  @DomName('Element.onsearch')
   @DocsEditable
   Stream<Event> get onSearch => searchEvent.forTarget(this);
 
-  @DomName('Element.select')
+  @DomName('Element.onselect')
   @DocsEditable
   Stream<Event> get onSelect => selectEvent.forTarget(this);
 
-  @DomName('Element.selectstart')
+  @DomName('Element.onselectstart')
   @DocsEditable
   Stream<Event> get onSelectStart => selectStartEvent.forTarget(this);
 
-  @DomName('Element.submit')
+  @DomName('Element.onsubmit')
   @DocsEditable
   Stream<Event> get onSubmit => submitEvent.forTarget(this);
 
-  @DomName('Element.touchcancel')
+  @DomName('Element.ontouchcancel')
   @DocsEditable
   Stream<TouchEvent> get onTouchCancel => touchCancelEvent.forTarget(this);
 
-  @DomName('Element.touchend')
+  @DomName('Element.ontouchend')
   @DocsEditable
   Stream<TouchEvent> get onTouchEnd => touchEndEvent.forTarget(this);
 
-  @DomName('Element.touchenter')
+  @DomName('Element.ontouchenter')
   @DocsEditable
   Stream<TouchEvent> get onTouchEnter => touchEnterEvent.forTarget(this);
 
-  @DomName('Element.touchleave')
+  @DomName('Element.ontouchleave')
   @DocsEditable
   Stream<TouchEvent> get onTouchLeave => touchLeaveEvent.forTarget(this);
 
-  @DomName('Element.touchmove')
+  @DomName('Element.ontouchmove')
   @DocsEditable
   Stream<TouchEvent> get onTouchMove => touchMoveEvent.forTarget(this);
 
-  @DomName('Element.touchstart')
+  @DomName('Element.ontouchstart')
   @DocsEditable
   Stream<TouchEvent> get onTouchStart => touchStartEvent.forTarget(this);
 
-  @DomName('Element.webkitTransitionEnd')
+  @DomName('Element.onwebkitTransitionEnd')
   @DocsEditable
   Stream<TransitionEvent> get onTransitionEnd => transitionEndEvent.forTarget(this);
 
-  @DomName('Element.webkitfullscreenchange')
+  @DomName('Element.onwebkitfullscreenchange')
   @DocsEditable
   Stream<Event> get onFullscreenChange => fullscreenChangeEvent.forTarget(this);
 
-  @DomName('Element.webkitfullscreenerror')
+  @DomName('Element.onwebkitfullscreenerror')
   @DocsEditable
   Stream<Event> get onFullscreenError => fullscreenErrorEvent.forTarget(this);
 
@@ -11084,15 +11078,15 @@
 class EventSource extends EventTarget {
   EventSource.internal() : super.internal();
 
-  @DomName('EventSource.error')
+  @DomName('EventSource.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('EventSource.message')
+  @DomName('EventSource.messageEvent')
   @DocsEditable
   static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
 
-  @DomName('EventSource.open')
+  @DomName('EventSource.openEvent')
   @DocsEditable
   static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');
 
@@ -11145,15 +11139,15 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "EventSource_removeEventListener_Callback";
 
-  @DomName('EventSource.error')
+  @DomName('EventSource.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('EventSource.message')
+  @DomName('EventSource.onmessage')
   @DocsEditable
   Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
 
-  @DomName('EventSource.open')
+  @DomName('EventSource.onopen')
   @DocsEditable
   Stream<Event> get onOpen => openEvent.forTarget(this);
 
@@ -11564,7 +11558,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(File element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(File element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -11732,27 +11726,27 @@
 class FileReader extends EventTarget {
   FileReader.internal() : super.internal();
 
-  @DomName('FileReader.abort')
+  @DomName('FileReader.abortEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> abortEvent = const EventStreamProvider<ProgressEvent>('abort');
 
-  @DomName('FileReader.error')
+  @DomName('FileReader.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('FileReader.load')
+  @DomName('FileReader.loadEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> loadEvent = const EventStreamProvider<ProgressEvent>('load');
 
-  @DomName('FileReader.loadend')
+  @DomName('FileReader.loadendEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> loadEndEvent = const EventStreamProvider<ProgressEvent>('loadend');
 
-  @DomName('FileReader.loadstart')
+  @DomName('FileReader.loadstartEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> loadStartEvent = const EventStreamProvider<ProgressEvent>('loadstart');
 
-  @DomName('FileReader.progress')
+  @DomName('FileReader.progressEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> progressEvent = const EventStreamProvider<ProgressEvent>('progress');
 
@@ -11834,27 +11828,27 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "FileReader_removeEventListener_Callback";
 
-  @DomName('FileReader.abort')
+  @DomName('FileReader.onabort')
   @DocsEditable
   Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);
 
-  @DomName('FileReader.error')
+  @DomName('FileReader.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('FileReader.load')
+  @DomName('FileReader.onload')
   @DocsEditable
   Stream<ProgressEvent> get onLoad => loadEvent.forTarget(this);
 
-  @DomName('FileReader.loadend')
+  @DomName('FileReader.onloadend')
   @DocsEditable
   Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);
 
-  @DomName('FileReader.loadstart')
+  @DomName('FileReader.onloadstart')
   @DocsEditable
   Stream<ProgressEvent> get onLoadStart => loadStartEvent.forTarget(this);
 
-  @DomName('FileReader.progress')
+  @DomName('FileReader.onprogress')
   @DocsEditable
   Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);
 
@@ -11998,27 +11992,27 @@
 class FileWriter extends EventTarget {
   FileWriter.internal() : super.internal();
 
-  @DomName('FileWriter.abort')
+  @DomName('FileWriter.abortEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> abortEvent = const EventStreamProvider<ProgressEvent>('abort');
 
-  @DomName('FileWriter.error')
+  @DomName('FileWriter.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('FileWriter.progress')
+  @DomName('FileWriter.progressEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> progressEvent = const EventStreamProvider<ProgressEvent>('progress');
 
-  @DomName('FileWriter.write')
+  @DomName('FileWriter.writeEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> writeEvent = const EventStreamProvider<ProgressEvent>('write');
 
-  @DomName('FileWriter.writeend')
+  @DomName('FileWriter.writeendEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> writeEndEvent = const EventStreamProvider<ProgressEvent>('writeend');
 
-  @DomName('FileWriter.writestart')
+  @DomName('FileWriter.writestartEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> writeStartEvent = const EventStreamProvider<ProgressEvent>('writestart');
 
@@ -12078,27 +12072,27 @@
   @DocsEditable
   void write(Blob data) native "FileWriter_write_Callback";
 
-  @DomName('FileWriter.abort')
+  @DomName('FileWriter.onabort')
   @DocsEditable
   Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);
 
-  @DomName('FileWriter.error')
+  @DomName('FileWriter.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('FileWriter.progress')
+  @DomName('FileWriter.onprogress')
   @DocsEditable
   Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);
 
-  @DomName('FileWriter.write')
+  @DomName('FileWriter.onwrite')
   @DocsEditable
   Stream<ProgressEvent> get onWrite => writeEvent.forTarget(this);
 
-  @DomName('FileWriter.writeend')
+  @DomName('FileWriter.onwriteend')
   @DocsEditable
   Stream<ProgressEvent> get onWriteEnd => writeEndEvent.forTarget(this);
 
-  @DomName('FileWriter.writestart')
+  @DomName('FileWriter.onwritestart')
   @DocsEditable
   Stream<ProgressEvent> get onWriteStart => writeStartEvent.forTarget(this);
 
@@ -12233,7 +12227,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(num element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(num element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -12468,7 +12462,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(num element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(num element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -13053,7 +13047,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Node element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Node element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -13262,7 +13256,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Node element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Node element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -13728,38 +13722,31 @@
 
   HttpRequest.internal() : super.internal();
 
-  /**
-   * Stop the current request.
-   *
-   * The request can only be stopped if readyState is `HEADERS_RECIEVED` or
-   * `LOADING`. If this method is not in the process of being sent, the method
-   * has no effect.
-   */
-  @DomName('XMLHttpRequest.abort')
+  @DomName('XMLHttpRequest.abortEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> abortEvent = const EventStreamProvider<ProgressEvent>('abort');
 
-  @DomName('XMLHttpRequest.error')
+  @DomName('XMLHttpRequest.errorEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> errorEvent = const EventStreamProvider<ProgressEvent>('error');
 
-  @DomName('XMLHttpRequest.load')
+  @DomName('XMLHttpRequest.loadEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> loadEvent = const EventStreamProvider<ProgressEvent>('load');
 
-  @DomName('XMLHttpRequest.loadend')
+  @DomName('XMLHttpRequest.loadendEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> loadEndEvent = const EventStreamProvider<ProgressEvent>('loadend');
 
-  @DomName('XMLHttpRequest.loadstart')
+  @DomName('XMLHttpRequest.loadstartEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> loadStartEvent = const EventStreamProvider<ProgressEvent>('loadstart');
 
-  @DomName('XMLHttpRequest.progress')
+  @DomName('XMLHttpRequest.progressEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> progressEvent = const EventStreamProvider<ProgressEvent>('progress');
 
-  @DomName('XMLHttpRequest.readystatechange')
+  @DomName('XMLHttpRequest.readystatechangeEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> readyStateChangeEvent = const EventStreamProvider<ProgressEvent>('readystatechange');
 
@@ -14027,37 +14014,61 @@
   void setRequestHeader(String header, String value) native "XMLHttpRequest_setRequestHeader_Callback";
 
   /**
-   * Stop the current request.
-   *
-   * The request can only be stopped if readyState is `HEADERS_RECIEVED` or
-   * `LOADING`. If this method is not in the process of being sent, the method
-   * has no effect.
+   * Event listeners to be notified when request has been aborted,
+   * generally due to calling `httpRequest.abort()`.
    */
-  @DomName('XMLHttpRequest.abort')
+  @DomName('XMLHttpRequest.onabort')
   @DocsEditable
   Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);
 
-  @DomName('XMLHttpRequest.error')
+  /**
+   * Event listeners to be notified when a request has failed, such as when a
+   * cross-domain error occurred or the file wasn't found on the server.
+   */
+  @DomName('XMLHttpRequest.onerror')
   @DocsEditable
   Stream<ProgressEvent> get onError => errorEvent.forTarget(this);
 
-  @DomName('XMLHttpRequest.load')
+  /**
+   * Event listeners to be notified once the request has completed
+   * *successfully*.
+   */
+  @DomName('XMLHttpRequest.onload')
   @DocsEditable
   Stream<ProgressEvent> get onLoad => loadEvent.forTarget(this);
 
-  @DomName('XMLHttpRequest.loadend')
+  /**
+   * Event listeners to be notified once the request has completed (on
+   * either success or failure).
+   */
+  @DomName('XMLHttpRequest.onloadend')
   @DocsEditable
   Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);
 
-  @DomName('XMLHttpRequest.loadstart')
+  /**
+   * Event listeners to be notified when the request starts, once
+   * `httpRequest.send()` has been called.
+   */
+  @DomName('XMLHttpRequest.onloadstart')
   @DocsEditable
   Stream<ProgressEvent> get onLoadStart => loadStartEvent.forTarget(this);
 
-  @DomName('XMLHttpRequest.progress')
+  /**
+   * Event listeners to be notified when data for the request
+   * is being sent or loaded.
+   *
+   * Progress events are fired every 50ms or for every byte transmitted,
+   * whichever is less frequent.
+   */
+  @DomName('XMLHttpRequest.onprogress')
   @DocsEditable
   Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);
 
-  @DomName('XMLHttpRequest.readystatechange')
+  /**
+   * Event listeners to be notified every time the [HttpRequest]
+   * object's `readyState` changes values.
+   */
+  @DomName('XMLHttpRequest.onreadystatechange')
   @DocsEditable
   Stream<ProgressEvent> get onReadyStateChange => readyStateChangeEvent.forTarget(this);
 
@@ -14162,27 +14173,27 @@
 class HttpRequestUpload extends EventTarget {
   HttpRequestUpload.internal() : super.internal();
 
-  @DomName('XMLHttpRequestUpload.abort')
+  @DomName('XMLHttpRequestUpload.abortEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> abortEvent = const EventStreamProvider<ProgressEvent>('abort');
 
-  @DomName('XMLHttpRequestUpload.error')
+  @DomName('XMLHttpRequestUpload.errorEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> errorEvent = const EventStreamProvider<ProgressEvent>('error');
 
-  @DomName('XMLHttpRequestUpload.load')
+  @DomName('XMLHttpRequestUpload.loadEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> loadEvent = const EventStreamProvider<ProgressEvent>('load');
 
-  @DomName('XMLHttpRequestUpload.loadend')
+  @DomName('XMLHttpRequestUpload.loadendEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> loadEndEvent = const EventStreamProvider<ProgressEvent>('loadend');
 
-  @DomName('XMLHttpRequestUpload.loadstart')
+  @DomName('XMLHttpRequestUpload.loadstartEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> loadStartEvent = const EventStreamProvider<ProgressEvent>('loadstart');
 
-  @DomName('XMLHttpRequestUpload.progress')
+  @DomName('XMLHttpRequestUpload.progressEvent')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> progressEvent = const EventStreamProvider<ProgressEvent>('progress');
 
@@ -14204,27 +14215,27 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "XMLHttpRequestUpload_removeEventListener_Callback";
 
-  @DomName('XMLHttpRequestUpload.abort')
+  @DomName('XMLHttpRequestUpload.onabort')
   @DocsEditable
   Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);
 
-  @DomName('XMLHttpRequestUpload.error')
+  @DomName('XMLHttpRequestUpload.onerror')
   @DocsEditable
   Stream<ProgressEvent> get onError => errorEvent.forTarget(this);
 
-  @DomName('XMLHttpRequestUpload.load')
+  @DomName('XMLHttpRequestUpload.onload')
   @DocsEditable
   Stream<ProgressEvent> get onLoad => loadEvent.forTarget(this);
 
-  @DomName('XMLHttpRequestUpload.loadend')
+  @DomName('XMLHttpRequestUpload.onloadend')
   @DocsEditable
   Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);
 
-  @DomName('XMLHttpRequestUpload.loadstart')
+  @DomName('XMLHttpRequestUpload.onloadstart')
   @DocsEditable
   Stream<ProgressEvent> get onLoadStart => loadStartEvent.forTarget(this);
 
-  @DomName('XMLHttpRequestUpload.progress')
+  @DomName('XMLHttpRequestUpload.onprogress')
   @DocsEditable
   Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);
 
@@ -14512,7 +14523,7 @@
   }
   InputElement.internal() : super.internal();
 
-  @DomName('HTMLInputElement.webkitSpeechChange')
+  @DomName('HTMLInputElement.webkitSpeechChangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> speechChangeEvent = const EventStreamProvider<Event>('webkitSpeechChange');
 
@@ -14956,7 +14967,7 @@
   @DocsEditable
   void _stepUp_2() native "HTMLInputElement__stepUp_2_Callback";
 
-  @DomName('HTMLInputElement.webkitSpeechChange')
+  @DomName('HTMLInputElement.onwebkitSpeechChange')
   @DocsEditable
   Stream<Event> get onSpeechChange => speechChangeEvent.forTarget(this);
 
@@ -15617,7 +15628,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(int element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(int element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -15852,7 +15863,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(int element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(int element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -16087,7 +16098,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(int element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(int element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -16915,103 +16926,103 @@
 class MediaElement extends _Element_Merged {
   MediaElement.internal() : super.internal();
 
-  @DomName('HTMLMediaElement.canplay')
+  @DomName('HTMLMediaElement.canplayEvent')
   @DocsEditable
   static const EventStreamProvider<Event> canPlayEvent = const EventStreamProvider<Event>('canplay');
 
-  @DomName('HTMLMediaElement.canplaythrough')
+  @DomName('HTMLMediaElement.canplaythroughEvent')
   @DocsEditable
   static const EventStreamProvider<Event> canPlayThroughEvent = const EventStreamProvider<Event>('canplaythrough');
 
-  @DomName('HTMLMediaElement.durationchange')
+  @DomName('HTMLMediaElement.durationchangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> durationChangeEvent = const EventStreamProvider<Event>('durationchange');
 
-  @DomName('HTMLMediaElement.emptied')
+  @DomName('HTMLMediaElement.emptiedEvent')
   @DocsEditable
   static const EventStreamProvider<Event> emptiedEvent = const EventStreamProvider<Event>('emptied');
 
-  @DomName('HTMLMediaElement.ended')
+  @DomName('HTMLMediaElement.endedEvent')
   @DocsEditable
   static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');
 
-  @DomName('HTMLMediaElement.loadeddata')
+  @DomName('HTMLMediaElement.loadeddataEvent')
   @DocsEditable
   static const EventStreamProvider<Event> loadedDataEvent = const EventStreamProvider<Event>('loadeddata');
 
-  @DomName('HTMLMediaElement.loadedmetadata')
+  @DomName('HTMLMediaElement.loadedmetadataEvent')
   @DocsEditable
   static const EventStreamProvider<Event> loadedMetadataEvent = const EventStreamProvider<Event>('loadedmetadata');
 
-  @DomName('HTMLMediaElement.loadstart')
+  @DomName('HTMLMediaElement.loadstartEvent')
   @DocsEditable
   static const EventStreamProvider<Event> loadStartEvent = const EventStreamProvider<Event>('loadstart');
 
-  @DomName('HTMLMediaElement.pause')
+  @DomName('HTMLMediaElement.pauseEvent')
   @DocsEditable
   static const EventStreamProvider<Event> pauseEvent = const EventStreamProvider<Event>('pause');
 
-  @DomName('HTMLMediaElement.play')
+  @DomName('HTMLMediaElement.playEvent')
   @DocsEditable
   static const EventStreamProvider<Event> playEvent = const EventStreamProvider<Event>('play');
 
-  @DomName('HTMLMediaElement.playing')
+  @DomName('HTMLMediaElement.playingEvent')
   @DocsEditable
   static const EventStreamProvider<Event> playingEvent = const EventStreamProvider<Event>('playing');
 
-  @DomName('HTMLMediaElement.progress')
+  @DomName('HTMLMediaElement.progressEvent')
   @DocsEditable
   static const EventStreamProvider<Event> progressEvent = const EventStreamProvider<Event>('progress');
 
-  @DomName('HTMLMediaElement.ratechange')
+  @DomName('HTMLMediaElement.ratechangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> rateChangeEvent = const EventStreamProvider<Event>('ratechange');
 
-  @DomName('HTMLMediaElement.seeked')
+  @DomName('HTMLMediaElement.seekedEvent')
   @DocsEditable
   static const EventStreamProvider<Event> seekedEvent = const EventStreamProvider<Event>('seeked');
 
-  @DomName('HTMLMediaElement.seeking')
+  @DomName('HTMLMediaElement.seekingEvent')
   @DocsEditable
   static const EventStreamProvider<Event> seekingEvent = const EventStreamProvider<Event>('seeking');
 
-  @DomName('HTMLMediaElement.show')
+  @DomName('HTMLMediaElement.showEvent')
   @DocsEditable
   static const EventStreamProvider<Event> showEvent = const EventStreamProvider<Event>('show');
 
-  @DomName('HTMLMediaElement.stalled')
+  @DomName('HTMLMediaElement.stalledEvent')
   @DocsEditable
   static const EventStreamProvider<Event> stalledEvent = const EventStreamProvider<Event>('stalled');
 
-  @DomName('HTMLMediaElement.suspend')
+  @DomName('HTMLMediaElement.suspendEvent')
   @DocsEditable
   static const EventStreamProvider<Event> suspendEvent = const EventStreamProvider<Event>('suspend');
 
-  @DomName('HTMLMediaElement.timeupdate')
+  @DomName('HTMLMediaElement.timeupdateEvent')
   @DocsEditable
   static const EventStreamProvider<Event> timeUpdateEvent = const EventStreamProvider<Event>('timeupdate');
 
-  @DomName('HTMLMediaElement.volumechange')
+  @DomName('HTMLMediaElement.volumechangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> volumeChangeEvent = const EventStreamProvider<Event>('volumechange');
 
-  @DomName('HTMLMediaElement.waiting')
+  @DomName('HTMLMediaElement.waitingEvent')
   @DocsEditable
   static const EventStreamProvider<Event> waitingEvent = const EventStreamProvider<Event>('waiting');
 
-  @DomName('HTMLMediaElement.webkitkeyadded')
+  @DomName('HTMLMediaElement.webkitkeyaddedEvent')
   @DocsEditable
   static const EventStreamProvider<MediaKeyEvent> keyAddedEvent = const EventStreamProvider<MediaKeyEvent>('webkitkeyadded');
 
-  @DomName('HTMLMediaElement.webkitkeyerror')
+  @DomName('HTMLMediaElement.webkitkeyerrorEvent')
   @DocsEditable
   static const EventStreamProvider<MediaKeyEvent> keyErrorEvent = const EventStreamProvider<MediaKeyEvent>('webkitkeyerror');
 
-  @DomName('HTMLMediaElement.webkitkeymessage')
+  @DomName('HTMLMediaElement.webkitkeymessageEvent')
   @DocsEditable
   static const EventStreamProvider<MediaKeyEvent> keyMessageEvent = const EventStreamProvider<MediaKeyEvent>('webkitkeymessage');
 
-  @DomName('HTMLMediaElement.webkitneedkey')
+  @DomName('HTMLMediaElement.webkitneedkeyEvent')
   @DocsEditable
   static const EventStreamProvider<MediaKeyEvent> needKeyEvent = const EventStreamProvider<MediaKeyEvent>('webkitneedkey');
 
@@ -17303,103 +17314,103 @@
   @DocsEditable
   void _webkitGenerateKeyRequest_2(keySystem) native "HTMLMediaElement__webkitGenerateKeyRequest_2_Callback";
 
-  @DomName('HTMLMediaElement.canplay')
+  @DomName('HTMLMediaElement.oncanplay')
   @DocsEditable
   Stream<Event> get onCanPlay => canPlayEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.canplaythrough')
+  @DomName('HTMLMediaElement.oncanplaythrough')
   @DocsEditable
   Stream<Event> get onCanPlayThrough => canPlayThroughEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.durationchange')
+  @DomName('HTMLMediaElement.ondurationchange')
   @DocsEditable
   Stream<Event> get onDurationChange => durationChangeEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.emptied')
+  @DomName('HTMLMediaElement.onemptied')
   @DocsEditable
   Stream<Event> get onEmptied => emptiedEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.ended')
+  @DomName('HTMLMediaElement.onended')
   @DocsEditable
   Stream<Event> get onEnded => endedEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.loadeddata')
+  @DomName('HTMLMediaElement.onloadeddata')
   @DocsEditable
   Stream<Event> get onLoadedData => loadedDataEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.loadedmetadata')
+  @DomName('HTMLMediaElement.onloadedmetadata')
   @DocsEditable
   Stream<Event> get onLoadedMetadata => loadedMetadataEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.loadstart')
+  @DomName('HTMLMediaElement.onloadstart')
   @DocsEditable
   Stream<Event> get onLoadStart => loadStartEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.pause')
+  @DomName('HTMLMediaElement.onpause')
   @DocsEditable
   Stream<Event> get onPause => pauseEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.play')
+  @DomName('HTMLMediaElement.onplay')
   @DocsEditable
   Stream<Event> get onPlay => playEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.playing')
+  @DomName('HTMLMediaElement.onplaying')
   @DocsEditable
   Stream<Event> get onPlaying => playingEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.progress')
+  @DomName('HTMLMediaElement.onprogress')
   @DocsEditable
   Stream<Event> get onProgress => progressEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.ratechange')
+  @DomName('HTMLMediaElement.onratechange')
   @DocsEditable
   Stream<Event> get onRateChange => rateChangeEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.seeked')
+  @DomName('HTMLMediaElement.onseeked')
   @DocsEditable
   Stream<Event> get onSeeked => seekedEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.seeking')
+  @DomName('HTMLMediaElement.onseeking')
   @DocsEditable
   Stream<Event> get onSeeking => seekingEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.show')
+  @DomName('HTMLMediaElement.onshow')
   @DocsEditable
   Stream<Event> get onShow => showEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.stalled')
+  @DomName('HTMLMediaElement.onstalled')
   @DocsEditable
   Stream<Event> get onStalled => stalledEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.suspend')
+  @DomName('HTMLMediaElement.onsuspend')
   @DocsEditable
   Stream<Event> get onSuspend => suspendEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.timeupdate')
+  @DomName('HTMLMediaElement.ontimeupdate')
   @DocsEditable
   Stream<Event> get onTimeUpdate => timeUpdateEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.volumechange')
+  @DomName('HTMLMediaElement.onvolumechange')
   @DocsEditable
   Stream<Event> get onVolumeChange => volumeChangeEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.waiting')
+  @DomName('HTMLMediaElement.onwaiting')
   @DocsEditable
   Stream<Event> get onWaiting => waitingEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.webkitkeyadded')
+  @DomName('HTMLMediaElement.onwebkitkeyadded')
   @DocsEditable
   Stream<MediaKeyEvent> get onKeyAdded => keyAddedEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.webkitkeyerror')
+  @DomName('HTMLMediaElement.onwebkitkeyerror')
   @DocsEditable
   Stream<MediaKeyEvent> get onKeyError => keyErrorEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.webkitkeymessage')
+  @DomName('HTMLMediaElement.onwebkitkeymessage')
   @DocsEditable
   Stream<MediaKeyEvent> get onKeyMessage => keyMessageEvent.forTarget(this);
 
-  @DomName('HTMLMediaElement.webkitneedkey')
+  @DomName('HTMLMediaElement.onwebkitneedkey')
   @DocsEditable
   Stream<MediaKeyEvent> get onNeedKey => needKeyEvent.forTarget(this);
 
@@ -17742,7 +17753,7 @@
 class MediaStream extends EventTarget {
   MediaStream.internal() : super.internal();
 
-  @DomName('MediaStream.ended')
+  @DomName('MediaStream.endedEvent')
   @DocsEditable
   static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');
 
@@ -17820,7 +17831,7 @@
   @DocsEditable
   void removeTrack(MediaStreamTrack track) native "MediaStream_removeTrack_Callback";
 
-  @DomName('MediaStream.ended')
+  @DomName('MediaStream.onended')
   @DocsEditable
   Stream<Event> get onEnded => endedEvent.forTarget(this);
 
@@ -17882,15 +17893,15 @@
 class MediaStreamTrack extends EventTarget {
   MediaStreamTrack.internal() : super.internal();
 
-  @DomName('MediaStreamTrack.ended')
+  @DomName('MediaStreamTrack.endedEvent')
   @DocsEditable
   static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');
 
-  @DomName('MediaStreamTrack.mute')
+  @DomName('MediaStreamTrack.muteEvent')
   @DocsEditable
   static const EventStreamProvider<Event> muteEvent = const EventStreamProvider<Event>('mute');
 
-  @DomName('MediaStreamTrack.unmute')
+  @DomName('MediaStreamTrack.unmuteEvent')
   @DocsEditable
   static const EventStreamProvider<Event> unmuteEvent = const EventStreamProvider<Event>('unmute');
 
@@ -17936,15 +17947,15 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "MediaStreamTrack_removeEventListener_Callback";
 
-  @DomName('MediaStreamTrack.ended')
+  @DomName('MediaStreamTrack.onended')
   @DocsEditable
   Stream<Event> get onEnded => endedEvent.forTarget(this);
 
-  @DomName('MediaStreamTrack.mute')
+  @DomName('MediaStreamTrack.onmute')
   @DocsEditable
   Stream<Event> get onMute => muteEvent.forTarget(this);
 
-  @DomName('MediaStreamTrack.unmute')
+  @DomName('MediaStreamTrack.onunmute')
   @DocsEditable
   Stream<Event> get onUnmute => unmuteEvent.forTarget(this);
 
@@ -18018,6 +18029,16 @@
 
 
 @DocsEditable
+/**
+ * An HTML <menu> element.
+ *
+ * A <menu> element represents an unordered list of menu commands.
+ *
+ * See also:
+ *
+ *  * [Menu Element](https://developer.mozilla.org/en-US/docs/HTML/Element/menu) from MDN.
+ *  * [Menu Element](http://www.w3.org/TR/html5/the-menu-element.html#the-menu-element) from the W3C.
+ */
 @DomName('HTMLMenuElement')
 class MenuElement extends _Element_Merged {
   MenuElement.internal() : super.internal();
@@ -18117,7 +18138,7 @@
 class MessagePort extends EventTarget {
   MessagePort.internal() : super.internal();
 
-  @DomName('MessagePort.message')
+  @DomName('MessagePort.messageEvent')
   @DocsEditable
   static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
 
@@ -18151,7 +18172,7 @@
   @DocsEditable
   void start() native "MessagePort_start_Callback";
 
-  @DomName('MessagePort.message')
+  @DomName('MessagePort.onmessage')
   @DocsEditable
   Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
 
@@ -18696,7 +18717,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Node element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Node element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -19163,7 +19184,7 @@
   }
 
   Iterable map(f(Node element)) {
-    return IterableMixinWorkaround.map(this, f);
+    return IterableMixinWorkaround.mapList(this, f);
   }
 
   List mappedBy(f(Node element)) {
@@ -19552,7 +19573,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Node element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Node element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -19741,23 +19762,23 @@
 class Notification extends EventTarget {
   Notification.internal() : super.internal();
 
-  @DomName('Notification.click')
+  @DomName('Notification.clickEvent')
   @DocsEditable
   static const EventStreamProvider<Event> clickEvent = const EventStreamProvider<Event>('click');
 
-  @DomName('Notification.close')
+  @DomName('Notification.closeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> closeEvent = const EventStreamProvider<Event>('close');
 
-  @DomName('Notification.display')
+  @DomName('Notification.displayEvent')
   @DocsEditable
   static const EventStreamProvider<Event> displayEvent = const EventStreamProvider<Event>('display');
 
-  @DomName('Notification.error')
+  @DomName('Notification.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('Notification.show')
+  @DomName('Notification.showEvent')
   @DocsEditable
   static const EventStreamProvider<Event> showEvent = const EventStreamProvider<Event>('show');
 
@@ -19832,23 +19853,23 @@
   @DocsEditable
   void show() native "Notification_show_Callback";
 
-  @DomName('Notification.click')
+  @DomName('Notification.onclick')
   @DocsEditable
   Stream<Event> get onClick => clickEvent.forTarget(this);
 
-  @DomName('Notification.close')
+  @DomName('Notification.onclose')
   @DocsEditable
   Stream<Event> get onClose => closeEvent.forTarget(this);
 
-  @DomName('Notification.display')
+  @DomName('Notification.ondisplay')
   @DocsEditable
   Stream<Event> get onDisplay => displayEvent.forTarget(this);
 
-  @DomName('Notification.error')
+  @DomName('Notification.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('Notification.show')
+  @DomName('Notification.onshow')
   @DocsEditable
   Stream<Event> get onShow => showEvent.forTarget(this);
 
@@ -19969,7 +19990,7 @@
 @DocsEditable
 @DomName('HTMLObjectElement')
 @SupportedBrowser(SupportedBrowser.CHROME)
-@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE)
 @SupportedBrowser(SupportedBrowser.SAFARI)
 class ObjectElement extends _Element_Merged {
   ObjectElement.internal() : super.internal();
@@ -21130,19 +21151,19 @@
 class RtcDataChannel extends EventTarget {
   RtcDataChannel.internal() : super.internal();
 
-  @DomName('RTCDataChannel.close')
+  @DomName('RTCDataChannel.closeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> closeEvent = const EventStreamProvider<Event>('close');
 
-  @DomName('RTCDataChannel.error')
+  @DomName('RTCDataChannel.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('RTCDataChannel.message')
+  @DomName('RTCDataChannel.messageEvent')
   @DocsEditable
   static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
 
-  @DomName('RTCDataChannel.open')
+  @DomName('RTCDataChannel.openEvent')
   @DocsEditable
   static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');
 
@@ -21228,19 +21249,19 @@
   @DocsEditable
   void _send_4(data) native "RTCDataChannel__send_4_Callback";
 
-  @DomName('RTCDataChannel.close')
+  @DomName('RTCDataChannel.onclose')
   @DocsEditable
   Stream<Event> get onClose => closeEvent.forTarget(this);
 
-  @DomName('RTCDataChannel.error')
+  @DomName('RTCDataChannel.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('RTCDataChannel.message')
+  @DomName('RTCDataChannel.onmessage')
   @DocsEditable
   Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
 
-  @DomName('RTCDataChannel.open')
+  @DomName('RTCDataChannel.onopen')
   @DocsEditable
   Stream<Event> get onOpen => openEvent.forTarget(this);
 
@@ -21344,31 +21365,31 @@
 class RtcPeerConnection extends EventTarget {
   RtcPeerConnection.internal() : super.internal();
 
-  @DomName('RTCPeerConnection.addstream')
+  @DomName('RTCPeerConnection.addstreamEvent')
   @DocsEditable
   static const EventStreamProvider<MediaStreamEvent> addStreamEvent = const EventStreamProvider<MediaStreamEvent>('addstream');
 
-  @DomName('RTCPeerConnection.datachannel')
+  @DomName('RTCPeerConnection.datachannelEvent')
   @DocsEditable
   static const EventStreamProvider<RtcDataChannelEvent> dataChannelEvent = const EventStreamProvider<RtcDataChannelEvent>('datachannel');
 
-  @DomName('RTCPeerConnection.icecandidate')
+  @DomName('RTCPeerConnection.icecandidateEvent')
   @DocsEditable
   static const EventStreamProvider<RtcIceCandidateEvent> iceCandidateEvent = const EventStreamProvider<RtcIceCandidateEvent>('icecandidate');
 
-  @DomName('RTCPeerConnection.icechange')
+  @DomName('RTCPeerConnection.icechangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> iceChangeEvent = const EventStreamProvider<Event>('icechange');
 
-  @DomName('RTCPeerConnection.negotiationneeded')
+  @DomName('RTCPeerConnection.negotiationneededEvent')
   @DocsEditable
   static const EventStreamProvider<Event> negotiationNeededEvent = const EventStreamProvider<Event>('negotiationneeded');
 
-  @DomName('RTCPeerConnection.removestream')
+  @DomName('RTCPeerConnection.removestreamEvent')
   @DocsEditable
   static const EventStreamProvider<MediaStreamEvent> removeStreamEvent = const EventStreamProvider<MediaStreamEvent>('removestream');
 
-  @DomName('RTCPeerConnection.statechange')
+  @DomName('RTCPeerConnection.statechangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> stateChangeEvent = const EventStreamProvider<Event>('statechange');
 
@@ -21475,31 +21496,31 @@
   @DocsEditable
   void updateIce([Map configuration, Map mediaConstraints]) native "RTCPeerConnection_updateIce_Callback";
 
-  @DomName('RTCPeerConnection.addstream')
+  @DomName('RTCPeerConnection.onaddstream')
   @DocsEditable
   Stream<MediaStreamEvent> get onAddStream => addStreamEvent.forTarget(this);
 
-  @DomName('RTCPeerConnection.datachannel')
+  @DomName('RTCPeerConnection.ondatachannel')
   @DocsEditable
   Stream<RtcDataChannelEvent> get onDataChannel => dataChannelEvent.forTarget(this);
 
-  @DomName('RTCPeerConnection.icecandidate')
+  @DomName('RTCPeerConnection.onicecandidate')
   @DocsEditable
   Stream<RtcIceCandidateEvent> get onIceCandidate => iceCandidateEvent.forTarget(this);
 
-  @DomName('RTCPeerConnection.icechange')
+  @DomName('RTCPeerConnection.onicechange')
   @DocsEditable
   Stream<Event> get onIceChange => iceChangeEvent.forTarget(this);
 
-  @DomName('RTCPeerConnection.negotiationneeded')
+  @DomName('RTCPeerConnection.onnegotiationneeded')
   @DocsEditable
   Stream<Event> get onNegotiationNeeded => negotiationNeededEvent.forTarget(this);
 
-  @DomName('RTCPeerConnection.removestream')
+  @DomName('RTCPeerConnection.onremovestream')
   @DocsEditable
   Stream<MediaStreamEvent> get onRemoveStream => removeStreamEvent.forTarget(this);
 
-  @DomName('RTCPeerConnection.statechange')
+  @DomName('RTCPeerConnection.onstatechange')
   @DocsEditable
   Stream<Event> get onStateChange => stateChangeEvent.forTarget(this);
 
@@ -22154,7 +22175,7 @@
 class SharedWorkerContext extends WorkerContext {
   SharedWorkerContext.internal() : super.internal();
 
-  @DomName('SharedWorkerContext.connect')
+  @DomName('SharedWorkerContext.connectEvent')
   @DocsEditable
   static const EventStreamProvider<Event> connectEvent = const EventStreamProvider<Event>('connect');
 
@@ -22168,7 +22189,7 @@
   @DocsEditable
   String get name native "SharedWorkerContext_name_Getter";
 
-  @DomName('SharedWorkerContext.connect')
+  @DomName('SharedWorkerContext.onconnect')
   @DocsEditable
   Stream<Event> get onConnect => connectEvent.forTarget(this);
 
@@ -22261,7 +22282,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(SourceBuffer element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(SourceBuffer element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -22579,7 +22600,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(SpeechGrammar element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(SpeechGrammar element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -22821,47 +22842,47 @@
 class SpeechRecognition extends EventTarget {
   SpeechRecognition.internal() : super.internal();
 
-  @DomName('SpeechRecognition.audioend')
+  @DomName('SpeechRecognition.audioendEvent')
   @DocsEditable
   static const EventStreamProvider<Event> audioEndEvent = const EventStreamProvider<Event>('audioend');
 
-  @DomName('SpeechRecognition.audiostart')
+  @DomName('SpeechRecognition.audiostartEvent')
   @DocsEditable
   static const EventStreamProvider<Event> audioStartEvent = const EventStreamProvider<Event>('audiostart');
 
-  @DomName('SpeechRecognition.end')
+  @DomName('SpeechRecognition.endEvent')
   @DocsEditable
   static const EventStreamProvider<Event> endEvent = const EventStreamProvider<Event>('end');
 
-  @DomName('SpeechRecognition.error')
+  @DomName('SpeechRecognition.errorEvent')
   @DocsEditable
   static const EventStreamProvider<SpeechRecognitionError> errorEvent = const EventStreamProvider<SpeechRecognitionError>('error');
 
-  @DomName('SpeechRecognition.nomatch')
+  @DomName('SpeechRecognition.nomatchEvent')
   @DocsEditable
   static const EventStreamProvider<SpeechRecognitionEvent> noMatchEvent = const EventStreamProvider<SpeechRecognitionEvent>('nomatch');
 
-  @DomName('SpeechRecognition.result')
+  @DomName('SpeechRecognition.resultEvent')
   @DocsEditable
   static const EventStreamProvider<SpeechRecognitionEvent> resultEvent = const EventStreamProvider<SpeechRecognitionEvent>('result');
 
-  @DomName('SpeechRecognition.soundend')
+  @DomName('SpeechRecognition.soundendEvent')
   @DocsEditable
   static const EventStreamProvider<Event> soundEndEvent = const EventStreamProvider<Event>('soundend');
 
-  @DomName('SpeechRecognition.soundstart')
+  @DomName('SpeechRecognition.soundstartEvent')
   @DocsEditable
   static const EventStreamProvider<Event> soundStartEvent = const EventStreamProvider<Event>('soundstart');
 
-  @DomName('SpeechRecognition.speechend')
+  @DomName('SpeechRecognition.speechendEvent')
   @DocsEditable
   static const EventStreamProvider<Event> speechEndEvent = const EventStreamProvider<Event>('speechend');
 
-  @DomName('SpeechRecognition.speechstart')
+  @DomName('SpeechRecognition.speechstartEvent')
   @DocsEditable
   static const EventStreamProvider<Event> speechStartEvent = const EventStreamProvider<Event>('speechstart');
 
-  @DomName('SpeechRecognition.start')
+  @DomName('SpeechRecognition.startEvent')
   @DocsEditable
   static const EventStreamProvider<Event> startEvent = const EventStreamProvider<Event>('start');
 
@@ -22947,47 +22968,47 @@
   @DocsEditable
   void stop() native "SpeechRecognition_stop_Callback";
 
-  @DomName('SpeechRecognition.audioend')
+  @DomName('SpeechRecognition.onaudioend')
   @DocsEditable
   Stream<Event> get onAudioEnd => audioEndEvent.forTarget(this);
 
-  @DomName('SpeechRecognition.audiostart')
+  @DomName('SpeechRecognition.onaudiostart')
   @DocsEditable
   Stream<Event> get onAudioStart => audioStartEvent.forTarget(this);
 
-  @DomName('SpeechRecognition.end')
+  @DomName('SpeechRecognition.onend')
   @DocsEditable
   Stream<Event> get onEnd => endEvent.forTarget(this);
 
-  @DomName('SpeechRecognition.error')
+  @DomName('SpeechRecognition.onerror')
   @DocsEditable
   Stream<SpeechRecognitionError> get onError => errorEvent.forTarget(this);
 
-  @DomName('SpeechRecognition.nomatch')
+  @DomName('SpeechRecognition.onnomatch')
   @DocsEditable
   Stream<SpeechRecognitionEvent> get onNoMatch => noMatchEvent.forTarget(this);
 
-  @DomName('SpeechRecognition.result')
+  @DomName('SpeechRecognition.onresult')
   @DocsEditable
   Stream<SpeechRecognitionEvent> get onResult => resultEvent.forTarget(this);
 
-  @DomName('SpeechRecognition.soundend')
+  @DomName('SpeechRecognition.onsoundend')
   @DocsEditable
   Stream<Event> get onSoundEnd => soundEndEvent.forTarget(this);
 
-  @DomName('SpeechRecognition.soundstart')
+  @DomName('SpeechRecognition.onsoundstart')
   @DocsEditable
   Stream<Event> get onSoundStart => soundStartEvent.forTarget(this);
 
-  @DomName('SpeechRecognition.speechend')
+  @DomName('SpeechRecognition.onspeechend')
   @DocsEditable
   Stream<Event> get onSpeechEnd => speechEndEvent.forTarget(this);
 
-  @DomName('SpeechRecognition.speechstart')
+  @DomName('SpeechRecognition.onspeechstart')
   @DocsEditable
   Stream<Event> get onSpeechStart => speechStartEvent.forTarget(this);
 
-  @DomName('SpeechRecognition.start')
+  @DomName('SpeechRecognition.onstart')
   @DocsEditable
   Stream<Event> get onStart => startEvent.forTarget(this);
 
@@ -23280,7 +23301,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Map element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Map element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -23481,6 +23502,31 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
+/**
+ * The type used by the
+ * [Window.localStorage] and [Window.sessionStorage] properties.
+ * Storage is implemented as a Map&lt;String, String>.
+ *
+ * To store and get values, use Dart's built-in map syntax:
+ *
+ *     window.localStorage['key1'] = 'val1';
+ *     window.localStorage['key2'] = 'val2';
+ *     window.localStorage['key3'] = 'val3';
+ *     assert(window.localStorage['key3'] == 'val3');
+ *
+ * You can use [Map](http://api.dartlang.org/dart_core/Map.html) APIs
+ * such as containsValue(), clear(), and length:
+ *
+ *     assert(window.localStorage.containsValue('does not exist') == false);
+ *     window.localStorage.clear();
+ *     assert(window.localStorage.length == 0);
+ *
+ * For more examples of using this API, see
+ * [localstorage_test.dart](http://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/tests/html/localstorage_test.dart).
+ * For details on using the Map API, see the
+ * [Maps](http://www.dartlang.org/docs/library-tour/#maps-aka-dictionaries-or-hashes)
+ * section of the library tour.
+ */
 @DomName('Storage')
 class Storage extends NativeFieldWrapperClass1 implements Map<String, String>
      {
@@ -24326,7 +24372,7 @@
 class TextTrack extends EventTarget {
   TextTrack.internal() : super.internal();
 
-  @DomName('TextTrack.cuechange')
+  @DomName('TextTrack.cuechangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> cueChangeEvent = const EventStreamProvider<Event>('cuechange');
 
@@ -24384,7 +24430,7 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "TextTrack_removeEventListener_Callback";
 
-  @DomName('TextTrack.cuechange')
+  @DomName('TextTrack.oncuechange')
   @DocsEditable
   Stream<Event> get onCueChange => cueChangeEvent.forTarget(this);
 
@@ -24411,11 +24457,11 @@
 class TextTrackCue extends EventTarget {
   TextTrackCue.internal() : super.internal();
 
-  @DomName('TextTrackCue.enter')
+  @DomName('TextTrackCue.enterEvent')
   @DocsEditable
   static const EventStreamProvider<Event> enterEvent = const EventStreamProvider<Event>('enter');
 
-  @DomName('TextTrackCue.exit')
+  @DomName('TextTrackCue.exitEvent')
   @DocsEditable
   static const EventStreamProvider<Event> exitEvent = const EventStreamProvider<Event>('exit');
 
@@ -24542,11 +24588,11 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "TextTrackCue_removeEventListener_Callback";
 
-  @DomName('TextTrackCue.enter')
+  @DomName('TextTrackCue.onenter')
   @DocsEditable
   Stream<Event> get onEnter => enterEvent.forTarget(this);
 
-  @DomName('TextTrackCue.exit')
+  @DomName('TextTrackCue.onexit')
   @DocsEditable
   Stream<Event> get onExit => exitEvent.forTarget(this);
 
@@ -24609,7 +24655,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(TextTrackCue element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(TextTrackCue element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -24781,7 +24827,7 @@
 class TextTrackList extends EventTarget implements List<TextTrack> {
   TextTrackList.internal() : super.internal();
 
-  @DomName('TextTrackList.addtrack')
+  @DomName('TextTrackList.addtrackEvent')
   @DocsEditable
   static const EventStreamProvider<TrackEvent> addTrackEvent = const EventStreamProvider<TrackEvent>('addtrack');
 
@@ -24824,7 +24870,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(TextTrack element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(TextTrack element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -24991,7 +25037,7 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "TextTrackList_removeEventListener_Callback";
 
-  @DomName('TextTrackList.addtrack')
+  @DomName('TextTrackList.onaddtrack')
   @DocsEditable
   Stream<TrackEvent> get onAddTrack => addTrackEvent.forTarget(this);
 
@@ -25187,18 +25233,24 @@
     return Event._isTypeSupported('TouchEvent');
   }
 }
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
 // WARNING: Do not edit - generated code.
 
 
-@DocsEditable
 @DomName('TouchList')
 class TouchList extends NativeFieldWrapperClass1 implements List<Touch> {
+  /// NB: This constructor likely does not work as you might expect it to! This
+  /// constructor will simply fail (returning null) if you are not on a device
+  /// with touch enabled. See dartbug.com/8314.
+  factory TouchList() => document.$dom_createTouchList();
   TouchList.internal();
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('TouchList.length')
   @DocsEditable
   int get length native "TouchList_length_Getter";
@@ -25232,7 +25284,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Touch element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Touch element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -25719,7 +25771,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(int element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(int element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -25954,7 +26006,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(int element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(int element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -26189,7 +26241,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(int element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(int element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -26422,7 +26474,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(int element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(int element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -28509,6 +28561,40 @@
 
 
 @DocsEditable
+/**
+ * Use the WebSocket interface to connect to a WebSocket,
+ * and to send and receive data on that WebSocket.
+ *
+ * To use a WebSocket in your web app, first create a WebSocket object,
+ * passing the WebSocket URL as an argument to the constructor.
+ *
+ *     var webSocket = new WebSocket('ws://127.0.0.1:1337/ws');
+ *
+ * To send data on the WebSocket, use the [send] method.
+ *
+ *     if (webSocket != null && webSocket.readyState == WebSocket.OPEN) {
+ *       webSocket.send(data);
+ *     } else {
+ *       print('WebSocket not connected, message $data not sent');
+ *     }
+ *
+ * To receive data on the WebSocket, register a listener for message events.
+ *
+ *     webSocket.on.message.add((MessageEvent e) {
+ *       receivedData(e.data);
+ *     });
+ *
+ * The message event handler receives a [MessageEvent] object
+ * as its sole argument.
+ * You can also define open, close, and error handlers,
+ * as specified by [WebSocketEvents].
+ *
+ * For more information, see the
+ * [WebSockets](http://www.dartlang.org/docs/library-tour/#html-websockets)
+ * section of the library tour and
+ * [Introducing WebSockets](http://www.html5rocks.com/en/tutorials/websockets/basics/),
+ * an HTML5Rocks.com tutorial.
+ */
 @DomName('WebSocket')
 @SupportedBrowser(SupportedBrowser.CHROME)
 @SupportedBrowser(SupportedBrowser.FIREFOX)
@@ -28517,19 +28603,19 @@
 class WebSocket extends EventTarget {
   WebSocket.internal() : super.internal();
 
-  @DomName('WebSocket.close')
+  @DomName('WebSocket.closeEvent')
   @DocsEditable
   static const EventStreamProvider<CloseEvent> closeEvent = const EventStreamProvider<CloseEvent>('close');
 
-  @DomName('WebSocket.error')
+  @DomName('WebSocket.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('WebSocket.message')
+  @DomName('WebSocket.messageEvent')
   @DocsEditable
   static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
 
-  @DomName('WebSocket.open')
+  @DomName('WebSocket.openEvent')
   @DocsEditable
   static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');
 
@@ -28647,19 +28733,19 @@
   @DocsEditable
   void send(data) native "WebSocket_send_Callback";
 
-  @DomName('WebSocket.close')
+  @DomName('WebSocket.onclose')
   @DocsEditable
   Stream<CloseEvent> get onClose => closeEvent.forTarget(this);
 
-  @DomName('WebSocket.error')
+  @DomName('WebSocket.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('WebSocket.message')
+  @DomName('WebSocket.onmessage')
   @DocsEditable
   Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
 
-  @DomName('WebSocket.open')
+  @DomName('WebSocket.onopen')
   @DocsEditable
   Stream<Event> get onOpen => openEvent.forTarget(this);
 
@@ -28792,71 +28878,71 @@
 
   Window.internal() : super.internal();
 
-  @DomName('DOMWindow.DOMContentLoaded')
+  @DomName('DOMWindow.DOMContentLoadedEvent')
   @DocsEditable
   static const EventStreamProvider<Event> contentLoadedEvent = const EventStreamProvider<Event>('DOMContentLoaded');
 
-  @DomName('DOMWindow.beforeunload')
+  @DomName('DOMWindow.beforeunloadEvent')
   @DocsEditable
   static const EventStreamProvider<Event> beforeUnloadEvent = const EventStreamProvider<Event>('beforeunload');
 
-  @DomName('DOMWindow.devicemotion')
+  @DomName('DOMWindow.devicemotionEvent')
   @DocsEditable
   static const EventStreamProvider<DeviceMotionEvent> deviceMotionEvent = const EventStreamProvider<DeviceMotionEvent>('devicemotion');
 
-  @DomName('DOMWindow.deviceorientation')
+  @DomName('DOMWindow.deviceorientationEvent')
   @DocsEditable
   static const EventStreamProvider<DeviceOrientationEvent> deviceOrientationEvent = const EventStreamProvider<DeviceOrientationEvent>('deviceorientation');
 
-  @DomName('DOMWindow.hashchange')
+  @DomName('DOMWindow.hashchangeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> hashChangeEvent = const EventStreamProvider<Event>('hashchange');
 
-  @DomName('DOMWindow.message')
+  @DomName('DOMWindow.messageEvent')
   @DocsEditable
   static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
 
-  @DomName('DOMWindow.offline')
+  @DomName('DOMWindow.offlineEvent')
   @DocsEditable
   static const EventStreamProvider<Event> offlineEvent = const EventStreamProvider<Event>('offline');
 
-  @DomName('DOMWindow.online')
+  @DomName('DOMWindow.onlineEvent')
   @DocsEditable
   static const EventStreamProvider<Event> onlineEvent = const EventStreamProvider<Event>('online');
 
-  @DomName('DOMWindow.pagehide')
+  @DomName('DOMWindow.pagehideEvent')
   @DocsEditable
   static const EventStreamProvider<Event> pageHideEvent = const EventStreamProvider<Event>('pagehide');
 
-  @DomName('DOMWindow.pageshow')
+  @DomName('DOMWindow.pageshowEvent')
   @DocsEditable
   static const EventStreamProvider<Event> pageShowEvent = const EventStreamProvider<Event>('pageshow');
 
-  @DomName('DOMWindow.popstate')
+  @DomName('DOMWindow.popstateEvent')
   @DocsEditable
   static const EventStreamProvider<PopStateEvent> popStateEvent = const EventStreamProvider<PopStateEvent>('popstate');
 
-  @DomName('DOMWindow.resize')
+  @DomName('DOMWindow.resizeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');
 
-  @DomName('DOMWindow.storage')
+  @DomName('DOMWindow.storageEvent')
   @DocsEditable
   static const EventStreamProvider<StorageEvent> storageEvent = const EventStreamProvider<StorageEvent>('storage');
 
-  @DomName('DOMWindow.unload')
+  @DomName('DOMWindow.unloadEvent')
   @DocsEditable
   static const EventStreamProvider<Event> unloadEvent = const EventStreamProvider<Event>('unload');
 
-  @DomName('DOMWindow.webkitAnimationEnd')
+  @DomName('DOMWindow.webkitAnimationEndEvent')
   @DocsEditable
   static const EventStreamProvider<AnimationEvent> animationEndEvent = const EventStreamProvider<AnimationEvent>('webkitAnimationEnd');
 
-  @DomName('DOMWindow.webkitAnimationIteration')
+  @DomName('DOMWindow.webkitAnimationIterationEvent')
   @DocsEditable
   static const EventStreamProvider<AnimationEvent> animationIterationEvent = const EventStreamProvider<AnimationEvent>('webkitAnimationIteration');
 
-  @DomName('DOMWindow.webkitAnimationStart')
+  @DomName('DOMWindow.webkitAnimationStartEvent')
   @DocsEditable
   static const EventStreamProvider<AnimationEvent> animationStartEvent = const EventStreamProvider<AnimationEvent>('webkitAnimationStart');
 
@@ -29255,219 +29341,219 @@
   @Experimental
   void resolveLocalFileSystemUrl(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native "DOMWindow_webkitResolveLocalFileSystemURL_Callback";
 
-  @DomName('DOMWindow.DOMContentLoaded')
+  @DomName('DOMWindow.onDOMContentLoaded')
   @DocsEditable
   Stream<Event> get onContentLoaded => contentLoadedEvent.forTarget(this);
 
-  @DomName('DOMWindow.abort')
+  @DomName('DOMWindow.onabort')
   @DocsEditable
   Stream<Event> get onAbort => Element.abortEvent.forTarget(this);
 
-  @DomName('DOMWindow.beforeunload')
+  @DomName('DOMWindow.onbeforeunload')
   @DocsEditable
   Stream<Event> get onBeforeUnload => beforeUnloadEvent.forTarget(this);
 
-  @DomName('DOMWindow.blur')
+  @DomName('DOMWindow.onblur')
   @DocsEditable
   Stream<Event> get onBlur => Element.blurEvent.forTarget(this);
 
-  @DomName('DOMWindow.change')
+  @DomName('DOMWindow.onchange')
   @DocsEditable
   Stream<Event> get onChange => Element.changeEvent.forTarget(this);
 
-  @DomName('DOMWindow.click')
+  @DomName('DOMWindow.onclick')
   @DocsEditable
   Stream<MouseEvent> get onClick => Element.clickEvent.forTarget(this);
 
-  @DomName('DOMWindow.contextmenu')
+  @DomName('DOMWindow.oncontextmenu')
   @DocsEditable
   Stream<MouseEvent> get onContextMenu => Element.contextMenuEvent.forTarget(this);
 
-  @DomName('DOMWindow.dblclick')
+  @DomName('DOMWindow.ondblclick')
   @DocsEditable
   Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);
 
-  @DomName('DOMWindow.devicemotion')
+  @DomName('DOMWindow.ondevicemotion')
   @DocsEditable
   Stream<DeviceMotionEvent> get onDeviceMotion => deviceMotionEvent.forTarget(this);
 
-  @DomName('DOMWindow.deviceorientation')
+  @DomName('DOMWindow.ondeviceorientation')
   @DocsEditable
   Stream<DeviceOrientationEvent> get onDeviceOrientation => deviceOrientationEvent.forTarget(this);
 
-  @DomName('DOMWindow.drag')
+  @DomName('DOMWindow.ondrag')
   @DocsEditable
   Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);
 
-  @DomName('DOMWindow.dragend')
+  @DomName('DOMWindow.ondragend')
   @DocsEditable
   Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);
 
-  @DomName('DOMWindow.dragenter')
+  @DomName('DOMWindow.ondragenter')
   @DocsEditable
   Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);
 
-  @DomName('DOMWindow.dragleave')
+  @DomName('DOMWindow.ondragleave')
   @DocsEditable
   Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);
 
-  @DomName('DOMWindow.dragover')
+  @DomName('DOMWindow.ondragover')
   @DocsEditable
   Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);
 
-  @DomName('DOMWindow.dragstart')
+  @DomName('DOMWindow.ondragstart')
   @DocsEditable
   Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);
 
-  @DomName('DOMWindow.drop')
+  @DomName('DOMWindow.ondrop')
   @DocsEditable
   Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);
 
-  @DomName('DOMWindow.error')
+  @DomName('DOMWindow.onerror')
   @DocsEditable
   Stream<Event> get onError => Element.errorEvent.forTarget(this);
 
-  @DomName('DOMWindow.focus')
+  @DomName('DOMWindow.onfocus')
   @DocsEditable
   Stream<Event> get onFocus => Element.focusEvent.forTarget(this);
 
-  @DomName('DOMWindow.hashchange')
+  @DomName('DOMWindow.onhashchange')
   @DocsEditable
   Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);
 
-  @DomName('DOMWindow.input')
+  @DomName('DOMWindow.oninput')
   @DocsEditable
   Stream<Event> get onInput => Element.inputEvent.forTarget(this);
 
-  @DomName('DOMWindow.invalid')
+  @DomName('DOMWindow.oninvalid')
   @DocsEditable
   Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);
 
-  @DomName('DOMWindow.keydown')
+  @DomName('DOMWindow.onkeydown')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);
 
-  @DomName('DOMWindow.keypress')
+  @DomName('DOMWindow.onkeypress')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);
 
-  @DomName('DOMWindow.keyup')
+  @DomName('DOMWindow.onkeyup')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);
 
-  @DomName('DOMWindow.load')
+  @DomName('DOMWindow.onload')
   @DocsEditable
   Stream<Event> get onLoad => Element.loadEvent.forTarget(this);
 
-  @DomName('DOMWindow.message')
+  @DomName('DOMWindow.onmessage')
   @DocsEditable
   Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
 
-  @DomName('DOMWindow.mousedown')
+  @DomName('DOMWindow.onmousedown')
   @DocsEditable
   Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);
 
-  @DomName('DOMWindow.mousemove')
+  @DomName('DOMWindow.onmousemove')
   @DocsEditable
   Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);
 
-  @DomName('DOMWindow.mouseout')
+  @DomName('DOMWindow.onmouseout')
   @DocsEditable
   Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);
 
-  @DomName('DOMWindow.mouseover')
+  @DomName('DOMWindow.onmouseover')
   @DocsEditable
   Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);
 
-  @DomName('DOMWindow.mouseup')
+  @DomName('DOMWindow.onmouseup')
   @DocsEditable
   Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);
 
-  @DomName('DOMWindow.mousewheel')
+  @DomName('DOMWindow.onmousewheel')
   @DocsEditable
   Stream<WheelEvent> get onMouseWheel => Element.mouseWheelEvent.forTarget(this);
 
-  @DomName('DOMWindow.offline')
+  @DomName('DOMWindow.onoffline')
   @DocsEditable
   Stream<Event> get onOffline => offlineEvent.forTarget(this);
 
-  @DomName('DOMWindow.online')
+  @DomName('DOMWindow.ononline')
   @DocsEditable
   Stream<Event> get onOnline => onlineEvent.forTarget(this);
 
-  @DomName('DOMWindow.pagehide')
+  @DomName('DOMWindow.onpagehide')
   @DocsEditable
   Stream<Event> get onPageHide => pageHideEvent.forTarget(this);
 
-  @DomName('DOMWindow.pageshow')
+  @DomName('DOMWindow.onpageshow')
   @DocsEditable
   Stream<Event> get onPageShow => pageShowEvent.forTarget(this);
 
-  @DomName('DOMWindow.popstate')
+  @DomName('DOMWindow.onpopstate')
   @DocsEditable
   Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);
 
-  @DomName('DOMWindow.reset')
+  @DomName('DOMWindow.onreset')
   @DocsEditable
   Stream<Event> get onReset => Element.resetEvent.forTarget(this);
 
-  @DomName('DOMWindow.resize')
+  @DomName('DOMWindow.onresize')
   @DocsEditable
   Stream<Event> get onResize => resizeEvent.forTarget(this);
 
-  @DomName('DOMWindow.scroll')
+  @DomName('DOMWindow.onscroll')
   @DocsEditable
   Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);
 
-  @DomName('DOMWindow.search')
+  @DomName('DOMWindow.onsearch')
   @DocsEditable
   Stream<Event> get onSearch => Element.searchEvent.forTarget(this);
 
-  @DomName('DOMWindow.select')
+  @DomName('DOMWindow.onselect')
   @DocsEditable
   Stream<Event> get onSelect => Element.selectEvent.forTarget(this);
 
-  @DomName('DOMWindow.storage')
+  @DomName('DOMWindow.onstorage')
   @DocsEditable
   Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);
 
-  @DomName('DOMWindow.submit')
+  @DomName('DOMWindow.onsubmit')
   @DocsEditable
   Stream<Event> get onSubmit => Element.submitEvent.forTarget(this);
 
-  @DomName('DOMWindow.touchcancel')
+  @DomName('DOMWindow.ontouchcancel')
   @DocsEditable
   Stream<TouchEvent> get onTouchCancel => Element.touchCancelEvent.forTarget(this);
 
-  @DomName('DOMWindow.touchend')
+  @DomName('DOMWindow.ontouchend')
   @DocsEditable
   Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);
 
-  @DomName('DOMWindow.touchmove')
+  @DomName('DOMWindow.ontouchmove')
   @DocsEditable
   Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);
 
-  @DomName('DOMWindow.touchstart')
+  @DomName('DOMWindow.ontouchstart')
   @DocsEditable
   Stream<TouchEvent> get onTouchStart => Element.touchStartEvent.forTarget(this);
 
-  @DomName('DOMWindow.unload')
+  @DomName('DOMWindow.onunload')
   @DocsEditable
   Stream<Event> get onUnload => unloadEvent.forTarget(this);
 
-  @DomName('DOMWindow.webkitAnimationEnd')
+  @DomName('DOMWindow.onwebkitAnimationEnd')
   @DocsEditable
   Stream<AnimationEvent> get onAnimationEnd => animationEndEvent.forTarget(this);
 
-  @DomName('DOMWindow.webkitAnimationIteration')
+  @DomName('DOMWindow.onwebkitAnimationIteration')
   @DocsEditable
   Stream<AnimationEvent> get onAnimationIteration => animationIterationEvent.forTarget(this);
 
-  @DomName('DOMWindow.webkitAnimationStart')
+  @DomName('DOMWindow.onwebkitAnimationStart')
   @DocsEditable
   Stream<AnimationEvent> get onAnimationStart => animationStartEvent.forTarget(this);
 
-  @DomName('DOMWindow.webkitTransitionEnd')
+  @DomName('DOMWindow.onwebkitTransitionEnd')
   @DocsEditable
   Stream<TransitionEvent> get onTransitionEnd => Element.transitionEndEvent.forTarget(this);
 
@@ -29713,7 +29799,7 @@
 class Worker extends AbstractWorker {
   Worker.internal() : super.internal();
 
-  @DomName('Worker.message')
+  @DomName('Worker.messageEvent')
   @DocsEditable
   static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
 
@@ -29740,7 +29826,7 @@
   @DocsEditable
   void terminate() native "Worker_terminate_Callback";
 
-  @DomName('Worker.message')
+  @DomName('Worker.onmessage')
   @DocsEditable
   Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
 
@@ -29767,7 +29853,7 @@
 class WorkerContext extends EventTarget {
   WorkerContext.internal() : super.internal();
 
-  @DomName('WorkerContext.error')
+  @DomName('WorkerContext.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
@@ -29879,7 +29965,7 @@
   @Experimental
   void resolveLocalFileSystemUrl(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native "WorkerContext_webkitResolveLocalFileSystemURL_Callback";
 
-  @DomName('WorkerContext.error')
+  @DomName('WorkerContext.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
@@ -30240,32 +30326,6 @@
 
 
 @DocsEditable
-@DomName('HTMLAppletElement')
-class _AppletElement extends _Element_Merged {
-  _AppletElement.internal() : super.internal();
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
-@DomName('HTMLBaseFontElement')
-class _BaseFontElement extends _Element_Merged {
-  _BaseFontElement.internal() : super.internal();
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
 @DomName('ClientRectList')
 class _ClientRectList extends NativeFieldWrapperClass1 implements List<ClientRect> {
   _ClientRectList.internal();
@@ -30303,7 +30363,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(ClientRect element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(ClientRect element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -30504,7 +30564,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(CssRule element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(CssRule element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -30705,7 +30765,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(CssValue element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(CssValue element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -30869,19 +30929,6 @@
 
 
 @DocsEditable
-@DomName('HTMLDirectoryElement')
-class _DirectoryElement extends _Element_Merged {
-  _DirectoryElement.internal() : super.internal();
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
 @DomName('HTMLElement')
 class _Element_Merged extends Element {
   _Element_Merged.internal() : super.internal();
@@ -31056,7 +31103,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Entry element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Entry element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -31257,7 +31304,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(EntrySync element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(EntrySync element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -31421,97 +31468,6 @@
 
 
 @DocsEditable
-@DomName('HTMLFontElement')
-class _FontElement extends _Element_Merged {
-  _FontElement.internal() : super.internal();
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
-@DomName('HTMLFrameElement')
-class _FrameElement extends _Element_Merged {
-  _FrameElement.internal() : super.internal();
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
-@DomName('HTMLFrameSetElement')
-class _FrameSetElement extends _Element_Merged {
-  _FrameSetElement.internal() : super.internal();
-
-  @DocsEditable
-  @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
-  @deprecated
-  _FrameSetElementEvents get on =>
-    new _FrameSetElementEvents(this);
-
-}
-
-@DocsEditable
-@deprecated
-class _FrameSetElementEvents extends ElementEvents {
-  @DocsEditable
-  _FrameSetElementEvents(EventTarget _ptr) : super(_ptr);
-
-  @DocsEditable
-  EventListenerList get beforeUnload => this['beforeunload'];
-
-  @DocsEditable
-  EventListenerList get blur => this['blur'];
-
-  @DocsEditable
-  EventListenerList get error => this['error'];
-
-  @DocsEditable
-  EventListenerList get focus => this['focus'];
-
-  @DocsEditable
-  EventListenerList get hashChange => this['hashchange'];
-
-  @DocsEditable
-  EventListenerList get load => this['load'];
-
-  @DocsEditable
-  EventListenerList get message => this['message'];
-
-  @DocsEditable
-  EventListenerList get offline => this['offline'];
-
-  @DocsEditable
-  EventListenerList get online => this['online'];
-
-  @DocsEditable
-  EventListenerList get popState => this['popstate'];
-
-  @DocsEditable
-  EventListenerList get resize => this['resize'];
-
-  @DocsEditable
-  EventListenerList get storage => this['storage'];
-
-  @DocsEditable
-  EventListenerList get unload => this['unload'];
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
 @DomName('GamepadList')
 class _GamepadList extends NativeFieldWrapperClass1 implements List<Gamepad> {
   _GamepadList.internal();
@@ -31549,7 +31505,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Gamepad element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Gamepad element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -31713,9 +31669,139 @@
 
 
 @DocsEditable
+@DomName('HTMLAppletElement')
+class _HTMLAppletElement extends _Element_Merged {
+  _HTMLAppletElement.internal() : super.internal();
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('HTMLBaseFontElement')
+class _HTMLBaseFontElement extends _Element_Merged {
+  _HTMLBaseFontElement.internal() : super.internal();
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('HTMLDirectoryElement')
+class _HTMLDirectoryElement extends _Element_Merged {
+  _HTMLDirectoryElement.internal() : super.internal();
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('HTMLFontElement')
+class _HTMLFontElement extends _Element_Merged {
+  _HTMLFontElement.internal() : super.internal();
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('HTMLFrameElement')
+class _HTMLFrameElement extends _Element_Merged {
+  _HTMLFrameElement.internal() : super.internal();
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('HTMLFrameSetElement')
+class _HTMLFrameSetElement extends _Element_Merged {
+  _HTMLFrameSetElement.internal() : super.internal();
+
+  @DocsEditable
+  @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
+  @deprecated
+  _HTMLFrameSetElementEvents get on =>
+    new _HTMLFrameSetElementEvents(this);
+
+}
+
+@DocsEditable
+@deprecated
+class _HTMLFrameSetElementEvents extends ElementEvents {
+  @DocsEditable
+  _HTMLFrameSetElementEvents(EventTarget _ptr) : super(_ptr);
+
+  @DocsEditable
+  EventListenerList get beforeUnload => this['beforeunload'];
+
+  @DocsEditable
+  EventListenerList get blur => this['blur'];
+
+  @DocsEditable
+  EventListenerList get error => this['error'];
+
+  @DocsEditable
+  EventListenerList get focus => this['focus'];
+
+  @DocsEditable
+  EventListenerList get hashChange => this['hashchange'];
+
+  @DocsEditable
+  EventListenerList get load => this['load'];
+
+  @DocsEditable
+  EventListenerList get message => this['message'];
+
+  @DocsEditable
+  EventListenerList get offline => this['offline'];
+
+  @DocsEditable
+  EventListenerList get online => this['online'];
+
+  @DocsEditable
+  EventListenerList get popState => this['popstate'];
+
+  @DocsEditable
+  EventListenerList get resize => this['resize'];
+
+  @DocsEditable
+  EventListenerList get storage => this['storage'];
+
+  @DocsEditable
+  EventListenerList get unload => this['unload'];
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
 @DomName('HTMLMarqueeElement')
-class _MarqueeElement extends _Element_Merged {
-  _MarqueeElement.internal() : super.internal();
+class _HTMLMarqueeElement extends _Element_Merged {
+  _HTMLMarqueeElement.internal() : super.internal();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -31763,7 +31849,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(MediaStream element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(MediaStream element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -31964,7 +32050,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(SpeechInputResult element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(SpeechInputResult element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -32165,7 +32251,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(SpeechRecognitionResult element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(SpeechRecognitionResult element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -32366,7 +32452,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(StyleSheet element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(StyleSheet element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
diff --git a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
index 8a37de0..fdc5c72 100644
--- a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
+++ b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
@@ -224,15 +224,15 @@
   Transaction _transaction(stores, mode) native;
 
 
-  @DomName('IDBDatabase.abort')
+  @DomName('IDBDatabase.abortEvent')
   @DocsEditable
   static const EventStreamProvider<Event> abortEvent = const EventStreamProvider<Event>('abort');
 
-  @DomName('IDBDatabase.error')
+  @DomName('IDBDatabase.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('IDBDatabase.versionchange')
+  @DomName('IDBDatabase.versionchangeEvent')
   @DocsEditable
   static const EventStreamProvider<UpgradeNeededEvent> versionChangeEvent = const EventStreamProvider<UpgradeNeededEvent>('versionchange');
 
@@ -294,15 +294,15 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
 
-  @DomName('IDBDatabase.abort')
+  @DomName('IDBDatabase.onabort')
   @DocsEditable
   Stream<Event> get onAbort => abortEvent.forTarget(this);
 
-  @DomName('IDBDatabase.error')
+  @DomName('IDBDatabase.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('IDBDatabase.versionchange')
+  @DomName('IDBDatabase.onversionchange')
   @DocsEditable
   Stream<UpgradeNeededEvent> get onVersionChange => versionChangeEvent.forTarget(this);
 }
@@ -646,11 +646,11 @@
 @DomName('IDBOpenDBRequest')
 class OpenDBRequest extends Request implements EventTarget native "*IDBOpenDBRequest" {
 
-  @DomName('IDBOpenDBRequest.blocked')
+  @DomName('IDBOpenDBRequest.blockedEvent')
   @DocsEditable
   static const EventStreamProvider<Event> blockedEvent = const EventStreamProvider<Event>('blocked');
 
-  @DomName('IDBOpenDBRequest.upgradeneeded')
+  @DomName('IDBOpenDBRequest.upgradeneededEvent')
   @DocsEditable
   static const EventStreamProvider<VersionChangeEvent> upgradeNeededEvent = const EventStreamProvider<VersionChangeEvent>('upgradeneeded');
 
@@ -660,11 +660,11 @@
   OpenDBRequestEvents get on =>
     new OpenDBRequestEvents(this);
 
-  @DomName('IDBOpenDBRequest.blocked')
+  @DomName('IDBOpenDBRequest.onblocked')
   @DocsEditable
   Stream<Event> get onBlocked => blockedEvent.forTarget(this);
 
-  @DomName('IDBOpenDBRequest.upgradeneeded')
+  @DomName('IDBOpenDBRequest.onupgradeneeded')
   @DocsEditable
   Stream<VersionChangeEvent> get onUpgradeNeeded => upgradeNeededEvent.forTarget(this);
 }
@@ -690,11 +690,11 @@
 @DomName('IDBRequest')
 class Request extends EventTarget native "*IDBRequest" {
 
-  @DomName('IDBRequest.error')
+  @DomName('IDBRequest.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('IDBRequest.success')
+  @DomName('IDBRequest.successEvent')
   @DocsEditable
   static const EventStreamProvider<Event> successEvent = const EventStreamProvider<Event>('success');
 
@@ -746,11 +746,11 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
 
-  @DomName('IDBRequest.error')
+  @DomName('IDBRequest.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('IDBRequest.success')
+  @DomName('IDBRequest.onsuccess')
   @DocsEditable
   Stream<Event> get onSuccess => successEvent.forTarget(this);
 }
@@ -776,15 +776,15 @@
 @DomName('IDBTransaction')
 class Transaction extends EventTarget native "*IDBTransaction" {
 
-  @DomName('IDBTransaction.abort')
+  @DomName('IDBTransaction.abortEvent')
   @DocsEditable
   static const EventStreamProvider<Event> abortEvent = const EventStreamProvider<Event>('abort');
 
-  @DomName('IDBTransaction.complete')
+  @DomName('IDBTransaction.completeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> completeEvent = const EventStreamProvider<Event>('complete');
 
-  @DomName('IDBTransaction.error')
+  @DomName('IDBTransaction.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
@@ -832,15 +832,15 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
 
-  @DomName('IDBTransaction.abort')
+  @DomName('IDBTransaction.onabort')
   @DocsEditable
   Stream<Event> get onAbort => abortEvent.forTarget(this);
 
-  @DomName('IDBTransaction.complete')
+  @DomName('IDBTransaction.oncomplete')
   @DocsEditable
   Stream<Event> get onComplete => completeEvent.forTarget(this);
 
-  @DomName('IDBTransaction.error')
+  @DomName('IDBTransaction.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 }
@@ -899,7 +899,7 @@
 @DomName('IDBVersionChangeRequest')
 class VersionChangeRequest extends Request implements EventTarget native "*IDBVersionChangeRequest" {
 
-  @DomName('IDBVersionChangeRequest.blocked')
+  @DomName('IDBVersionChangeRequest.blockedEvent')
   @DocsEditable
   static const EventStreamProvider<Event> blockedEvent = const EventStreamProvider<Event>('blocked');
 
@@ -909,7 +909,7 @@
   VersionChangeRequestEvents get on =>
     new VersionChangeRequestEvents(this);
 
-  @DomName('IDBVersionChangeRequest.blocked')
+  @DomName('IDBVersionChangeRequest.onblocked')
   @DocsEditable
   Stream<Event> get onBlocked => blockedEvent.forTarget(this);
 }
@@ -930,5 +930,5 @@
 
 @DocsEditable
 @DomName('IDBAny')
-class _Any native "*IDBAny" {
+class _IDBAny native "*IDBAny" {
 }
diff --git a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
index 184fb00..44cdb37 100644
--- a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
+++ b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
@@ -124,15 +124,15 @@
 class Database extends EventTarget {
   Database.internal() : super.internal();
 
-  @DomName('IDBDatabase.abort')
+  @DomName('IDBDatabase.abortEvent')
   @DocsEditable
   static const EventStreamProvider<Event> abortEvent = const EventStreamProvider<Event>('abort');
 
-  @DomName('IDBDatabase.error')
+  @DomName('IDBDatabase.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('IDBDatabase.versionchange')
+  @DomName('IDBDatabase.versionchangeEvent')
   @DocsEditable
   static const EventStreamProvider<UpgradeNeededEvent> versionChangeEvent = const EventStreamProvider<UpgradeNeededEvent>('versionchange');
 
@@ -203,15 +203,15 @@
   @DocsEditable
   Transaction _transaction_3(storeName_OR_storeNames, mode) native "IDBDatabase__transaction_3_Callback";
 
-  @DomName('IDBDatabase.abort')
+  @DomName('IDBDatabase.onabort')
   @DocsEditable
   Stream<Event> get onAbort => abortEvent.forTarget(this);
 
-  @DomName('IDBDatabase.error')
+  @DomName('IDBDatabase.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('IDBDatabase.versionchange')
+  @DomName('IDBDatabase.onversionchange')
   @DocsEditable
   Stream<UpgradeNeededEvent> get onVersionChange => versionChangeEvent.forTarget(this);
 
@@ -757,11 +757,11 @@
 class OpenDBRequest extends Request implements EventTarget {
   OpenDBRequest.internal() : super.internal();
 
-  @DomName('IDBOpenDBRequest.blocked')
+  @DomName('IDBOpenDBRequest.blockedEvent')
   @DocsEditable
   static const EventStreamProvider<Event> blockedEvent = const EventStreamProvider<Event>('blocked');
 
-  @DomName('IDBOpenDBRequest.upgradeneeded')
+  @DomName('IDBOpenDBRequest.upgradeneededEvent')
   @DocsEditable
   static const EventStreamProvider<VersionChangeEvent> upgradeNeededEvent = const EventStreamProvider<VersionChangeEvent>('upgradeneeded');
 
@@ -771,11 +771,11 @@
   OpenDBRequestEvents get on =>
     new OpenDBRequestEvents(this);
 
-  @DomName('IDBOpenDBRequest.blocked')
+  @DomName('IDBOpenDBRequest.onblocked')
   @DocsEditable
   Stream<Event> get onBlocked => blockedEvent.forTarget(this);
 
-  @DomName('IDBOpenDBRequest.upgradeneeded')
+  @DomName('IDBOpenDBRequest.onupgradeneeded')
   @DocsEditable
   Stream<VersionChangeEvent> get onUpgradeNeeded => upgradeNeededEvent.forTarget(this);
 
@@ -805,11 +805,11 @@
 class Request extends EventTarget {
   Request.internal() : super.internal();
 
-  @DomName('IDBRequest.error')
+  @DomName('IDBRequest.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('IDBRequest.success')
+  @DomName('IDBRequest.successEvent')
   @DocsEditable
   static const EventStreamProvider<Event> successEvent = const EventStreamProvider<Event>('success');
 
@@ -855,11 +855,11 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "IDBRequest_removeEventListener_Callback";
 
-  @DomName('IDBRequest.error')
+  @DomName('IDBRequest.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('IDBRequest.success')
+  @DomName('IDBRequest.onsuccess')
   @DocsEditable
   Stream<Event> get onSuccess => successEvent.forTarget(this);
 
@@ -889,15 +889,15 @@
 class Transaction extends EventTarget {
   Transaction.internal() : super.internal();
 
-  @DomName('IDBTransaction.abort')
+  @DomName('IDBTransaction.abortEvent')
   @DocsEditable
   static const EventStreamProvider<Event> abortEvent = const EventStreamProvider<Event>('abort');
 
-  @DomName('IDBTransaction.complete')
+  @DomName('IDBTransaction.completeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> completeEvent = const EventStreamProvider<Event>('complete');
 
-  @DomName('IDBTransaction.error')
+  @DomName('IDBTransaction.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
@@ -943,15 +943,15 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "IDBTransaction_removeEventListener_Callback";
 
-  @DomName('IDBTransaction.abort')
+  @DomName('IDBTransaction.onabort')
   @DocsEditable
   Stream<Event> get onAbort => abortEvent.forTarget(this);
 
-  @DomName('IDBTransaction.complete')
+  @DomName('IDBTransaction.oncomplete')
   @DocsEditable
   Stream<Event> get onComplete => completeEvent.forTarget(this);
 
-  @DomName('IDBTransaction.error')
+  @DomName('IDBTransaction.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
@@ -1022,7 +1022,7 @@
 class VersionChangeRequest extends Request implements EventTarget {
   VersionChangeRequest.internal() : super.internal();
 
-  @DomName('IDBVersionChangeRequest.blocked')
+  @DomName('IDBVersionChangeRequest.blockedEvent')
   @DocsEditable
   static const EventStreamProvider<Event> blockedEvent = const EventStreamProvider<Event>('blocked');
 
@@ -1032,7 +1032,7 @@
   VersionChangeRequestEvents get on =>
     new VersionChangeRequestEvents(this);
 
-  @DomName('IDBVersionChangeRequest.blocked')
+  @DomName('IDBVersionChangeRequest.onblocked')
   @DocsEditable
   Stream<Event> get onBlocked => blockedEvent.forTarget(this);
 
@@ -1056,7 +1056,7 @@
 
 @DocsEditable
 @DomName('IDBAny')
-class _Any extends NativeFieldWrapperClass1 {
-  _Any.internal();
+class _IDBAny extends NativeFieldWrapperClass1 {
+  _IDBAny.internal();
 
 }
diff --git a/sdk/lib/svg/dart2js/svg_dart2js.dart b/sdk/lib/svg/dart2js/svg_dart2js.dart
index 1f52ee3..092dc7c 100644
--- a/sdk/lib/svg/dart2js/svg_dart2js.dart
+++ b/sdk/lib/svg/dart2js/svg_dart2js.dart
@@ -151,18 +151,19 @@
 
 
 @DocsEditable
-@DomName('SVGAltGlyphDefElement')
-class AltGlyphDefElement extends SvgElement native "*SVGAltGlyphDefElement" {
-}
-// 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.
-
-
-@DocsEditable
 @DomName('SVGAltGlyphElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class AltGlyphElement extends TextPositioningElement implements UriReference native "*SVGAltGlyphElement" {
 
+  @DomName('SVGAltGlyphElement.SVGAltGlyphElement')
+  @DocsEditable
+  factory AltGlyphElement() => _SvgElementFactoryProvider.createSvgElement_tag("altGlyph");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('altGlyph') && (new SvgElement.tag('altGlyph') is AltGlyphElement);
+
   @DomName('SVGAltGlyphElement.format')
   @DocsEditable
   String format;
@@ -183,15 +184,6 @@
 
 
 @DocsEditable
-@DomName('SVGAltGlyphItemElement')
-class AltGlyphItemElement extends SvgElement native "*SVGAltGlyphItemElement" {
-}
-// 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.
-
-
-@DocsEditable
 @DomName('SVGAngle')
 class Angle native "*SVGAngle" {
 
@@ -235,25 +227,18 @@
 
 
 @DocsEditable
-@DomName('SVGAnimateColorElement')
-class AnimateColorElement extends AnimationElement native "*SVGAnimateColorElement" {
-
-  @DomName('SVGAnimateColorElement.SVGAnimateColorElement')
-  @DocsEditable
-  factory AnimateColorElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateColor");
-}
-// 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.
-
-
-@DocsEditable
 @DomName('SVGAnimateElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class AnimateElement extends AnimationElement native "*SVGAnimateElement" {
 
   @DomName('SVGAnimateElement.SVGAnimateElement')
   @DocsEditable
   factory AnimateElement() => _SvgElementFactoryProvider.createSvgElement_tag("animate");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('animate') && (new SvgElement.tag('animate') is AnimateElement);
 }
 // 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
@@ -262,11 +247,17 @@
 
 @DocsEditable
 @DomName('SVGAnimateMotionElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class AnimateMotionElement extends AnimationElement native "*SVGAnimateMotionElement" {
 
   @DomName('SVGAnimateMotionElement.SVGAnimateMotionElement')
   @DocsEditable
   factory AnimateMotionElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateMotion");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('animateMotion') && (new SvgElement.tag('animateMotion') is AnimateMotionElement);
 }
 // 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
@@ -275,11 +266,17 @@
 
 @DocsEditable
 @DomName('SVGAnimateTransformElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class AnimateTransformElement extends AnimationElement native "*SVGAnimateTransformElement" {
 
   @DomName('SVGAnimateTransformElement.SVGAnimateTransformElement')
   @DocsEditable
   factory AnimateTransformElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateTransform");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('animateTransform') && (new SvgElement.tag('animateTransform') is AnimateTransformElement);
 }
 // 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
@@ -779,106 +776,6 @@
 
 
 @DocsEditable
-@DomName('SVGComponentTransferFunctionElement')
-class ComponentTransferFunctionElement extends SvgElement native "*SVGComponentTransferFunctionElement" {
-
-  static const int SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE = 3;
-
-  static const int SVG_FECOMPONENTTRANSFER_TYPE_GAMMA = 5;
-
-  static const int SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY = 1;
-
-  static const int SVG_FECOMPONENTTRANSFER_TYPE_LINEAR = 4;
-
-  static const int SVG_FECOMPONENTTRANSFER_TYPE_TABLE = 2;
-
-  static const int SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN = 0;
-
-  @DomName('SVGComponentTransferFunctionElement.amplitude')
-  @DocsEditable
-  final AnimatedNumber amplitude;
-
-  @DomName('SVGComponentTransferFunctionElement.exponent')
-  @DocsEditable
-  final AnimatedNumber exponent;
-
-  @DomName('SVGComponentTransferFunctionElement.intercept')
-  @DocsEditable
-  final AnimatedNumber intercept;
-
-  @DomName('SVGComponentTransferFunctionElement.offset')
-  @DocsEditable
-  final AnimatedNumber offset;
-
-  @DomName('SVGComponentTransferFunctionElement.slope')
-  @DocsEditable
-  final AnimatedNumber slope;
-
-  @DomName('SVGComponentTransferFunctionElement.tableValues')
-  @DocsEditable
-  final AnimatedNumberList tableValues;
-
-  @DomName('SVGComponentTransferFunctionElement.type')
-  @DocsEditable
-  final AnimatedEnumeration type;
-}
-// 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.
-
-
-@DocsEditable
-@DomName('SVGCursorElement')
-class CursorElement extends SvgElement implements UriReference, Tests, ExternalResourcesRequired native "*SVGCursorElement" {
-
-  @DomName('SVGCursorElement.SVGCursorElement')
-  @DocsEditable
-  factory CursorElement() => _SvgElementFactoryProvider.createSvgElement_tag("cursor");
-
-  @DomName('SVGCursorElement.x')
-  @DocsEditable
-  final AnimatedLength x;
-
-  @DomName('SVGCursorElement.y')
-  @DocsEditable
-  final AnimatedLength y;
-
-  // From SVGExternalResourcesRequired
-
-  @DomName('SVGCursorElement.externalResourcesRequired')
-  @DocsEditable
-  final AnimatedBoolean externalResourcesRequired;
-
-  // From SVGTests
-
-  @DomName('SVGCursorElement.requiredExtensions')
-  @DocsEditable
-  final StringList requiredExtensions;
-
-  @DomName('SVGCursorElement.requiredFeatures')
-  @DocsEditable
-  final StringList requiredFeatures;
-
-  @DomName('SVGCursorElement.systemLanguage')
-  @DocsEditable
-  final StringList systemLanguage;
-
-  @DomName('SVGCursorElement.hasExtension')
-  @DocsEditable
-  bool hasExtension(String extension) native;
-
-  // From SVGURIReference
-
-  @DomName('SVGCursorElement.href')
-  @DocsEditable
-  final AnimatedString href;
-}
-// 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.
-
-
-@DocsEditable
 @DomName('SVGDefsElement')
 class DefsElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGDefsElement" {
 
@@ -986,163 +883,163 @@
 @DomName('SVGElementInstance')
 class ElementInstance extends EventTarget native "*SVGElementInstance" {
 
-  @DomName('SVGElementInstance.abort')
+  @DomName('SVGElementInstance.abortEvent')
   @DocsEditable
   static const EventStreamProvider<Event> abortEvent = const EventStreamProvider<Event>('abort');
 
-  @DomName('SVGElementInstance.beforecopy')
+  @DomName('SVGElementInstance.beforecopyEvent')
   @DocsEditable
   static const EventStreamProvider<Event> beforeCopyEvent = const EventStreamProvider<Event>('beforecopy');
 
-  @DomName('SVGElementInstance.beforecut')
+  @DomName('SVGElementInstance.beforecutEvent')
   @DocsEditable
   static const EventStreamProvider<Event> beforeCutEvent = const EventStreamProvider<Event>('beforecut');
 
-  @DomName('SVGElementInstance.beforepaste')
+  @DomName('SVGElementInstance.beforepasteEvent')
   @DocsEditable
   static const EventStreamProvider<Event> beforePasteEvent = const EventStreamProvider<Event>('beforepaste');
 
-  @DomName('SVGElementInstance.blur')
+  @DomName('SVGElementInstance.blurEvent')
   @DocsEditable
   static const EventStreamProvider<Event> blurEvent = const EventStreamProvider<Event>('blur');
 
-  @DomName('SVGElementInstance.change')
+  @DomName('SVGElementInstance.changeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');
 
-  @DomName('SVGElementInstance.click')
+  @DomName('SVGElementInstance.clickEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> clickEvent = const EventStreamProvider<MouseEvent>('click');
 
-  @DomName('SVGElementInstance.contextmenu')
+  @DomName('SVGElementInstance.contextmenuEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> contextMenuEvent = const EventStreamProvider<MouseEvent>('contextmenu');
 
-  @DomName('SVGElementInstance.copy')
+  @DomName('SVGElementInstance.copyEvent')
   @DocsEditable
   static const EventStreamProvider<Event> copyEvent = const EventStreamProvider<Event>('copy');
 
-  @DomName('SVGElementInstance.cut')
+  @DomName('SVGElementInstance.cutEvent')
   @DocsEditable
   static const EventStreamProvider<Event> cutEvent = const EventStreamProvider<Event>('cut');
 
-  @DomName('SVGElementInstance.dblclick')
+  @DomName('SVGElementInstance.dblclickEvent')
   @DocsEditable
   static const EventStreamProvider<Event> doubleClickEvent = const EventStreamProvider<Event>('dblclick');
 
-  @DomName('SVGElementInstance.drag')
+  @DomName('SVGElementInstance.dragEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragEvent = const EventStreamProvider<MouseEvent>('drag');
 
-  @DomName('SVGElementInstance.dragend')
+  @DomName('SVGElementInstance.dragendEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragEndEvent = const EventStreamProvider<MouseEvent>('dragend');
 
-  @DomName('SVGElementInstance.dragenter')
+  @DomName('SVGElementInstance.dragenterEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragEnterEvent = const EventStreamProvider<MouseEvent>('dragenter');
 
-  @DomName('SVGElementInstance.dragleave')
+  @DomName('SVGElementInstance.dragleaveEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragLeaveEvent = const EventStreamProvider<MouseEvent>('dragleave');
 
-  @DomName('SVGElementInstance.dragover')
+  @DomName('SVGElementInstance.dragoverEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragOverEvent = const EventStreamProvider<MouseEvent>('dragover');
 
-  @DomName('SVGElementInstance.dragstart')
+  @DomName('SVGElementInstance.dragstartEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragStartEvent = const EventStreamProvider<MouseEvent>('dragstart');
 
-  @DomName('SVGElementInstance.drop')
+  @DomName('SVGElementInstance.dropEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dropEvent = const EventStreamProvider<MouseEvent>('drop');
 
-  @DomName('SVGElementInstance.error')
+  @DomName('SVGElementInstance.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('SVGElementInstance.focus')
+  @DomName('SVGElementInstance.focusEvent')
   @DocsEditable
   static const EventStreamProvider<Event> focusEvent = const EventStreamProvider<Event>('focus');
 
-  @DomName('SVGElementInstance.input')
+  @DomName('SVGElementInstance.inputEvent')
   @DocsEditable
   static const EventStreamProvider<Event> inputEvent = const EventStreamProvider<Event>('input');
 
-  @DomName('SVGElementInstance.keydown')
+  @DomName('SVGElementInstance.keydownEvent')
   @DocsEditable
   static const EventStreamProvider<KeyboardEvent> keyDownEvent = const EventStreamProvider<KeyboardEvent>('keydown');
 
-  @DomName('SVGElementInstance.keypress')
+  @DomName('SVGElementInstance.keypressEvent')
   @DocsEditable
   static const EventStreamProvider<KeyboardEvent> keyPressEvent = const EventStreamProvider<KeyboardEvent>('keypress');
 
-  @DomName('SVGElementInstance.keyup')
+  @DomName('SVGElementInstance.keyupEvent')
   @DocsEditable
   static const EventStreamProvider<KeyboardEvent> keyUpEvent = const EventStreamProvider<KeyboardEvent>('keyup');
 
-  @DomName('SVGElementInstance.load')
+  @DomName('SVGElementInstance.loadEvent')
   @DocsEditable
   static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');
 
-  @DomName('SVGElementInstance.mousedown')
+  @DomName('SVGElementInstance.mousedownEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> mouseDownEvent = const EventStreamProvider<MouseEvent>('mousedown');
 
-  @DomName('SVGElementInstance.mousemove')
+  @DomName('SVGElementInstance.mousemoveEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> mouseMoveEvent = const EventStreamProvider<MouseEvent>('mousemove');
 
-  @DomName('SVGElementInstance.mouseout')
+  @DomName('SVGElementInstance.mouseoutEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> mouseOutEvent = const EventStreamProvider<MouseEvent>('mouseout');
 
-  @DomName('SVGElementInstance.mouseover')
+  @DomName('SVGElementInstance.mouseoverEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> mouseOverEvent = const EventStreamProvider<MouseEvent>('mouseover');
 
-  @DomName('SVGElementInstance.mouseup')
+  @DomName('SVGElementInstance.mouseupEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> mouseUpEvent = const EventStreamProvider<MouseEvent>('mouseup');
 
-  @DomName('SVGElementInstance.mousewheel')
+  @DomName('SVGElementInstance.mousewheelEvent')
   @DocsEditable
   static const EventStreamProvider<WheelEvent> mouseWheelEvent = const EventStreamProvider<WheelEvent>('mousewheel');
 
-  @DomName('SVGElementInstance.paste')
+  @DomName('SVGElementInstance.pasteEvent')
   @DocsEditable
   static const EventStreamProvider<Event> pasteEvent = const EventStreamProvider<Event>('paste');
 
-  @DomName('SVGElementInstance.reset')
+  @DomName('SVGElementInstance.resetEvent')
   @DocsEditable
   static const EventStreamProvider<Event> resetEvent = const EventStreamProvider<Event>('reset');
 
-  @DomName('SVGElementInstance.resize')
+  @DomName('SVGElementInstance.resizeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');
 
-  @DomName('SVGElementInstance.scroll')
+  @DomName('SVGElementInstance.scrollEvent')
   @DocsEditable
   static const EventStreamProvider<Event> scrollEvent = const EventStreamProvider<Event>('scroll');
 
-  @DomName('SVGElementInstance.search')
+  @DomName('SVGElementInstance.searchEvent')
   @DocsEditable
   static const EventStreamProvider<Event> searchEvent = const EventStreamProvider<Event>('search');
 
-  @DomName('SVGElementInstance.select')
+  @DomName('SVGElementInstance.selectEvent')
   @DocsEditable
   static const EventStreamProvider<Event> selectEvent = const EventStreamProvider<Event>('select');
 
-  @DomName('SVGElementInstance.selectstart')
+  @DomName('SVGElementInstance.selectstartEvent')
   @DocsEditable
   static const EventStreamProvider<Event> selectStartEvent = const EventStreamProvider<Event>('selectstart');
 
-  @DomName('SVGElementInstance.submit')
+  @DomName('SVGElementInstance.submitEvent')
   @DocsEditable
   static const EventStreamProvider<Event> submitEvent = const EventStreamProvider<Event>('submit');
 
-  @DomName('SVGElementInstance.unload')
+  @DomName('SVGElementInstance.unloadEvent')
   @DocsEditable
   static const EventStreamProvider<Event> unloadEvent = const EventStreamProvider<Event>('unload');
 
@@ -1186,163 +1083,163 @@
   @DocsEditable
   final ElementInstance previousSibling;
 
-  @DomName('SVGElementInstance.abort')
+  @DomName('SVGElementInstance.onabort')
   @DocsEditable
   Stream<Event> get onAbort => abortEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.beforecopy')
+  @DomName('SVGElementInstance.onbeforecopy')
   @DocsEditable
   Stream<Event> get onBeforeCopy => beforeCopyEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.beforecut')
+  @DomName('SVGElementInstance.onbeforecut')
   @DocsEditable
   Stream<Event> get onBeforeCut => beforeCutEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.beforepaste')
+  @DomName('SVGElementInstance.onbeforepaste')
   @DocsEditable
   Stream<Event> get onBeforePaste => beforePasteEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.blur')
+  @DomName('SVGElementInstance.onblur')
   @DocsEditable
   Stream<Event> get onBlur => blurEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.change')
+  @DomName('SVGElementInstance.onchange')
   @DocsEditable
   Stream<Event> get onChange => changeEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.click')
+  @DomName('SVGElementInstance.onclick')
   @DocsEditable
   Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.contextmenu')
+  @DomName('SVGElementInstance.oncontextmenu')
   @DocsEditable
   Stream<MouseEvent> get onContextMenu => contextMenuEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.copy')
+  @DomName('SVGElementInstance.oncopy')
   @DocsEditable
   Stream<Event> get onCopy => copyEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.cut')
+  @DomName('SVGElementInstance.oncut')
   @DocsEditable
   Stream<Event> get onCut => cutEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.dblclick')
+  @DomName('SVGElementInstance.ondblclick')
   @DocsEditable
   Stream<Event> get onDoubleClick => doubleClickEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.drag')
+  @DomName('SVGElementInstance.ondrag')
   @DocsEditable
   Stream<MouseEvent> get onDrag => dragEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.dragend')
+  @DomName('SVGElementInstance.ondragend')
   @DocsEditable
   Stream<MouseEvent> get onDragEnd => dragEndEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.dragenter')
+  @DomName('SVGElementInstance.ondragenter')
   @DocsEditable
   Stream<MouseEvent> get onDragEnter => dragEnterEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.dragleave')
+  @DomName('SVGElementInstance.ondragleave')
   @DocsEditable
   Stream<MouseEvent> get onDragLeave => dragLeaveEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.dragover')
+  @DomName('SVGElementInstance.ondragover')
   @DocsEditable
   Stream<MouseEvent> get onDragOver => dragOverEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.dragstart')
+  @DomName('SVGElementInstance.ondragstart')
   @DocsEditable
   Stream<MouseEvent> get onDragStart => dragStartEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.drop')
+  @DomName('SVGElementInstance.ondrop')
   @DocsEditable
   Stream<MouseEvent> get onDrop => dropEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.error')
+  @DomName('SVGElementInstance.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.focus')
+  @DomName('SVGElementInstance.onfocus')
   @DocsEditable
   Stream<Event> get onFocus => focusEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.input')
+  @DomName('SVGElementInstance.oninput')
   @DocsEditable
   Stream<Event> get onInput => inputEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.keydown')
+  @DomName('SVGElementInstance.onkeydown')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyDown => keyDownEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.keypress')
+  @DomName('SVGElementInstance.onkeypress')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyPress => keyPressEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.keyup')
+  @DomName('SVGElementInstance.onkeyup')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyUp => keyUpEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.load')
+  @DomName('SVGElementInstance.onload')
   @DocsEditable
   Stream<Event> get onLoad => loadEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.mousedown')
+  @DomName('SVGElementInstance.onmousedown')
   @DocsEditable
   Stream<MouseEvent> get onMouseDown => mouseDownEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.mousemove')
+  @DomName('SVGElementInstance.onmousemove')
   @DocsEditable
   Stream<MouseEvent> get onMouseMove => mouseMoveEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.mouseout')
+  @DomName('SVGElementInstance.onmouseout')
   @DocsEditable
   Stream<MouseEvent> get onMouseOut => mouseOutEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.mouseover')
+  @DomName('SVGElementInstance.onmouseover')
   @DocsEditable
   Stream<MouseEvent> get onMouseOver => mouseOverEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.mouseup')
+  @DomName('SVGElementInstance.onmouseup')
   @DocsEditable
   Stream<MouseEvent> get onMouseUp => mouseUpEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.mousewheel')
+  @DomName('SVGElementInstance.onmousewheel')
   @DocsEditable
   Stream<WheelEvent> get onMouseWheel => mouseWheelEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.paste')
+  @DomName('SVGElementInstance.onpaste')
   @DocsEditable
   Stream<Event> get onPaste => pasteEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.reset')
+  @DomName('SVGElementInstance.onreset')
   @DocsEditable
   Stream<Event> get onReset => resetEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.resize')
+  @DomName('SVGElementInstance.onresize')
   @DocsEditable
   Stream<Event> get onResize => resizeEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.scroll')
+  @DomName('SVGElementInstance.onscroll')
   @DocsEditable
   Stream<Event> get onScroll => scrollEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.search')
+  @DomName('SVGElementInstance.onsearch')
   @DocsEditable
   Stream<Event> get onSearch => searchEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.select')
+  @DomName('SVGElementInstance.onselect')
   @DocsEditable
   Stream<Event> get onSelect => selectEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.selectstart')
+  @DomName('SVGElementInstance.onselectstart')
   @DocsEditable
   Stream<Event> get onSelectStart => selectStartEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.submit')
+  @DomName('SVGElementInstance.onsubmit')
   @DocsEditable
   Stream<Event> get onSubmit => submitEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.unload')
+  @DomName('SVGElementInstance.onunload')
   @DocsEditable
   Stream<Event> get onUnload => unloadEvent.forTarget(this);
 }
@@ -1594,6 +1491,9 @@
 @DomName('SVGExternalResourcesRequired')
 abstract class ExternalResourcesRequired {
 
+  /// Checks if this type is supported on the current platform.
+  static bool supported(SvgElement element) => JS('bool', '#.externalResourcesRequired !== undefined && #.externalResourcesRequired.animVal !== undefined', element, element);
+
   AnimatedBoolean externalResourcesRequired;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -1603,8 +1503,19 @@
 
 @DocsEditable
 @DomName('SVGFEBlendElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEBlendElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEBlendElement" {
 
+  @DomName('SVGFEBlendElement.SVGFEBlendElement')
+  @DocsEditable
+  factory FEBlendElement() => _SvgElementFactoryProvider.createSvgElement_tag("feBlend");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feBlend') && (new SvgElement.tag('feBlend') is FEBlendElement);
+
   static const int SVG_FEBLEND_MODE_DARKEN = 4;
 
   static const int SVG_FEBLEND_MODE_LIGHTEN = 5;
@@ -1658,8 +1569,19 @@
 
 @DocsEditable
 @DomName('SVGFEColorMatrixElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEColorMatrixElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEColorMatrixElement" {
 
+  @DomName('SVGFEColorMatrixElement.SVGFEColorMatrixElement')
+  @DocsEditable
+  factory FEColorMatrixElement() => _SvgElementFactoryProvider.createSvgElement_tag("feColorMatrix");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feColorMatrix') && (new SvgElement.tag('feColorMatrix') is FEColorMatrixElement);
+
   static const int SVG_FECOLORMATRIX_TYPE_HUEROTATE = 3;
 
   static const int SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA = 4;
@@ -1711,8 +1633,19 @@
 
 @DocsEditable
 @DomName('SVGFEComponentTransferElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEComponentTransferElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEComponentTransferElement" {
 
+  @DomName('SVGFEComponentTransferElement.SVGFEComponentTransferElement')
+  @DocsEditable
+  factory FEComponentTransferElement() => _SvgElementFactoryProvider.createSvgElement_tag("feComponentTransfer");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feComponentTransfer') && (new SvgElement.tag('feComponentTransfer') is FEComponentTransferElement);
+
   @DomName('SVGFEComponentTransferElement.in1')
   @DocsEditable
   final AnimatedString in1;
@@ -1819,8 +1752,19 @@
 
 @DocsEditable
 @DomName('SVGFEConvolveMatrixElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEConvolveMatrixElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEConvolveMatrixElement" {
 
+  @DomName('SVGFEConvolveMatrixElement.SVGFEConvolveMatrixElement')
+  @DocsEditable
+  factory FEConvolveMatrixElement() => _SvgElementFactoryProvider.createSvgElement_tag("feConvolveMatrix");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feConvolveMatrix') && (new SvgElement.tag('feConvolveMatrix') is FEConvolveMatrixElement);
+
   static const int SVG_EDGEMODE_DUPLICATE = 1;
 
   static const int SVG_EDGEMODE_NONE = 3;
@@ -1906,8 +1850,19 @@
 
 @DocsEditable
 @DomName('SVGFEDiffuseLightingElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEDiffuseLightingElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEDiffuseLightingElement" {
 
+  @DomName('SVGFEDiffuseLightingElement.SVGFEDiffuseLightingElement')
+  @DocsEditable
+  factory FEDiffuseLightingElement() => _SvgElementFactoryProvider.createSvgElement_tag("feDiffuseLighting");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feDiffuseLighting') && (new SvgElement.tag('feDiffuseLighting') is FEDiffuseLightingElement);
+
   @DomName('SVGFEDiffuseLightingElement.diffuseConstant')
   @DocsEditable
   final AnimatedNumber diffuseConstant;
@@ -1957,8 +1912,19 @@
 
 @DocsEditable
 @DomName('SVGFEDisplacementMapElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEDisplacementMapElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEDisplacementMapElement" {
 
+  @DomName('SVGFEDisplacementMapElement.SVGFEDisplacementMapElement')
+  @DocsEditable
+  factory FEDisplacementMapElement() => _SvgElementFactoryProvider.createSvgElement_tag("feDisplacementMap");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feDisplacementMap') && (new SvgElement.tag('feDisplacementMap') is FEDisplacementMapElement);
+
   static const int SVG_CHANNEL_A = 4;
 
   static const int SVG_CHANNEL_B = 3;
@@ -2018,8 +1984,19 @@
 
 @DocsEditable
 @DomName('SVGFEDistantLightElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEDistantLightElement extends SvgElement native "*SVGFEDistantLightElement" {
 
+  @DomName('SVGFEDistantLightElement.SVGFEDistantLightElement')
+  @DocsEditable
+  factory FEDistantLightElement() => _SvgElementFactoryProvider.createSvgElement_tag("feDistantLight");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feDistantLight') && (new SvgElement.tag('feDistantLight') is FEDistantLightElement);
+
   @DomName('SVGFEDistantLightElement.azimuth')
   @DocsEditable
   final AnimatedNumber azimuth;
@@ -2034,64 +2011,20 @@
 
 
 @DocsEditable
-@DomName('SVGFEDropShadowElement')
-class FEDropShadowElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEDropShadowElement" {
-
-  @DomName('SVGFEDropShadowElement.dx')
-  @DocsEditable
-  final AnimatedNumber dx;
-
-  @DomName('SVGFEDropShadowElement.dy')
-  @DocsEditable
-  final AnimatedNumber dy;
-
-  @DomName('SVGFEDropShadowElement.in1')
-  @DocsEditable
-  final AnimatedString in1;
-
-  @DomName('SVGFEDropShadowElement.stdDeviationX')
-  @DocsEditable
-  final AnimatedNumber stdDeviationX;
-
-  @DomName('SVGFEDropShadowElement.stdDeviationY')
-  @DocsEditable
-  final AnimatedNumber stdDeviationY;
-
-  @DomName('SVGFEDropShadowElement.setStdDeviation')
-  @DocsEditable
-  void setStdDeviation(num stdDeviationX, num stdDeviationY) native;
-
-  // From SVGFilterPrimitiveStandardAttributes
-
-  @DomName('SVGFEDropShadowElement.height')
-  @DocsEditable
-  final AnimatedLength height;
-
-  @DomName('SVGFEDropShadowElement.result')
-  @DocsEditable
-  final AnimatedString result;
-
-  @DomName('SVGFEDropShadowElement.width')
-  @DocsEditable
-  final AnimatedLength width;
-
-  @DomName('SVGFEDropShadowElement.x')
-  @DocsEditable
-  final AnimatedLength x;
-
-  @DomName('SVGFEDropShadowElement.y')
-  @DocsEditable
-  final AnimatedLength y;
-}
-// 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.
-
-
-@DocsEditable
 @DomName('SVGFEFloodElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEFloodElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEFloodElement" {
 
+  @DomName('SVGFEFloodElement.SVGFEFloodElement')
+  @DocsEditable
+  factory FEFloodElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFlood");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feFlood') && (new SvgElement.tag('feFlood') is FEFloodElement);
+
   // From SVGFilterPrimitiveStandardAttributes
 
   @DomName('SVGFEFloodElement.height')
@@ -2121,7 +2054,18 @@
 
 @DocsEditable
 @DomName('SVGFEFuncAElement')
-class FEFuncAElement extends ComponentTransferFunctionElement native "*SVGFEFuncAElement" {
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+class FEFuncAElement extends _SVGComponentTransferFunctionElement native "*SVGFEFuncAElement" {
+
+  @DomName('SVGFEFuncAElement.SVGFEFuncAElement')
+  @DocsEditable
+  factory FEFuncAElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncA");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feFuncA') && (new SvgElement.tag('feFuncA') is FEFuncAElement);
 }
 // 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
@@ -2130,7 +2074,18 @@
 
 @DocsEditable
 @DomName('SVGFEFuncBElement')
-class FEFuncBElement extends ComponentTransferFunctionElement native "*SVGFEFuncBElement" {
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+class FEFuncBElement extends _SVGComponentTransferFunctionElement native "*SVGFEFuncBElement" {
+
+  @DomName('SVGFEFuncBElement.SVGFEFuncBElement')
+  @DocsEditable
+  factory FEFuncBElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncB");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feFuncB') && (new SvgElement.tag('feFuncB') is FEFuncBElement);
 }
 // 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
@@ -2139,7 +2094,18 @@
 
 @DocsEditable
 @DomName('SVGFEFuncGElement')
-class FEFuncGElement extends ComponentTransferFunctionElement native "*SVGFEFuncGElement" {
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+class FEFuncGElement extends _SVGComponentTransferFunctionElement native "*SVGFEFuncGElement" {
+
+  @DomName('SVGFEFuncGElement.SVGFEFuncGElement')
+  @DocsEditable
+  factory FEFuncGElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncG");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feFuncG') && (new SvgElement.tag('feFuncG') is FEFuncGElement);
 }
 // 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
@@ -2148,7 +2114,18 @@
 
 @DocsEditable
 @DomName('SVGFEFuncRElement')
-class FEFuncRElement extends ComponentTransferFunctionElement native "*SVGFEFuncRElement" {
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+class FEFuncRElement extends _SVGComponentTransferFunctionElement native "*SVGFEFuncRElement" {
+
+  @DomName('SVGFEFuncRElement.SVGFEFuncRElement')
+  @DocsEditable
+  factory FEFuncRElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncR");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feFuncR') && (new SvgElement.tag('feFuncR') is FEFuncRElement);
 }
 // 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
@@ -2157,8 +2134,19 @@
 
 @DocsEditable
 @DomName('SVGFEGaussianBlurElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEGaussianBlurElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEGaussianBlurElement" {
 
+  @DomName('SVGFEGaussianBlurElement.SVGFEGaussianBlurElement')
+  @DocsEditable
+  factory FEGaussianBlurElement() => _SvgElementFactoryProvider.createSvgElement_tag("feGaussianBlur");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feGaussianBlur') && (new SvgElement.tag('feGaussianBlur') is FEGaussianBlurElement);
+
   @DomName('SVGFEGaussianBlurElement.in1')
   @DocsEditable
   final AnimatedString in1;
@@ -2204,8 +2192,19 @@
 
 @DocsEditable
 @DomName('SVGFEImageElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEImageElement extends StyledElement implements FilterPrimitiveStandardAttributes, UriReference, ExternalResourcesRequired, LangSpace native "*SVGFEImageElement" {
 
+  @DomName('SVGFEImageElement.SVGFEImageElement')
+  @DocsEditable
+  factory FEImageElement() => _SvgElementFactoryProvider.createSvgElement_tag("feImage");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feImage') && (new SvgElement.tag('feImage') is FEImageElement);
+
   @DomName('SVGFEImageElement.preserveAspectRatio')
   @DocsEditable
   final AnimatedPreserveAspectRatio preserveAspectRatio;
@@ -2261,8 +2260,19 @@
 
 @DocsEditable
 @DomName('SVGFEMergeElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEMergeElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEMergeElement" {
 
+  @DomName('SVGFEMergeElement.SVGFEMergeElement')
+  @DocsEditable
+  factory FEMergeElement() => _SvgElementFactoryProvider.createSvgElement_tag("feMerge");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feMerge') && (new SvgElement.tag('feMerge') is FEMergeElement);
+
   // From SVGFilterPrimitiveStandardAttributes
 
   @DomName('SVGFEMergeElement.height')
@@ -2292,8 +2302,19 @@
 
 @DocsEditable
 @DomName('SVGFEMergeNodeElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEMergeNodeElement extends SvgElement native "*SVGFEMergeNodeElement" {
 
+  @DomName('SVGFEMergeNodeElement.SVGFEMergeNodeElement')
+  @DocsEditable
+  factory FEMergeNodeElement() => _SvgElementFactoryProvider.createSvgElement_tag("feMergeNode");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feMergeNode') && (new SvgElement.tag('feMergeNode') is FEMergeNodeElement);
+
   @DomName('SVGFEMergeNodeElement.in1')
   @DocsEditable
   final AnimatedString in1;
@@ -2362,8 +2383,19 @@
 
 @DocsEditable
 @DomName('SVGFEOffsetElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEOffsetElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEOffsetElement" {
 
+  @DomName('SVGFEOffsetElement.SVGFEOffsetElement')
+  @DocsEditable
+  factory FEOffsetElement() => _SvgElementFactoryProvider.createSvgElement_tag("feOffset");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feOffset') && (new SvgElement.tag('feOffset') is FEOffsetElement);
+
   @DomName('SVGFEOffsetElement.dx')
   @DocsEditable
   final AnimatedNumber dx;
@@ -2405,8 +2437,19 @@
 
 @DocsEditable
 @DomName('SVGFEPointLightElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEPointLightElement extends SvgElement native "*SVGFEPointLightElement" {
 
+  @DomName('SVGFEPointLightElement.SVGFEPointLightElement')
+  @DocsEditable
+  factory FEPointLightElement() => _SvgElementFactoryProvider.createSvgElement_tag("fePointLight");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('fePointLight') && (new SvgElement.tag('fePointLight') is FEPointLightElement);
+
   @DomName('SVGFEPointLightElement.x')
   @DocsEditable
   final AnimatedNumber x;
@@ -2426,8 +2469,19 @@
 
 @DocsEditable
 @DomName('SVGFESpecularLightingElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FESpecularLightingElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFESpecularLightingElement" {
 
+  @DomName('SVGFESpecularLightingElement.SVGFESpecularLightingElement')
+  @DocsEditable
+  factory FESpecularLightingElement() => _SvgElementFactoryProvider.createSvgElement_tag("feSpecularLighting");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feSpecularLighting') && (new SvgElement.tag('feSpecularLighting') is FESpecularLightingElement);
+
   @DomName('SVGFESpecularLightingElement.in1')
   @DocsEditable
   final AnimatedString in1;
@@ -2473,8 +2527,19 @@
 
 @DocsEditable
 @DomName('SVGFESpotLightElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FESpotLightElement extends SvgElement native "*SVGFESpotLightElement" {
 
+  @DomName('SVGFESpotLightElement.SVGFESpotLightElement')
+  @DocsEditable
+  factory FESpotLightElement() => _SvgElementFactoryProvider.createSvgElement_tag("feSpotLight");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feSpotLight') && (new SvgElement.tag('feSpotLight') is FESpotLightElement);
+
   @DomName('SVGFESpotLightElement.limitingConeAngle')
   @DocsEditable
   final AnimatedNumber limitingConeAngle;
@@ -2514,8 +2579,19 @@
 
 @DocsEditable
 @DomName('SVGFETileElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FETileElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFETileElement" {
 
+  @DomName('SVGFETileElement.SVGFETileElement')
+  @DocsEditable
+  factory FETileElement() => _SvgElementFactoryProvider.createSvgElement_tag("feTile");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feTile') && (new SvgElement.tag('feTile') is FETileElement);
+
   @DomName('SVGFETileElement.in1')
   @DocsEditable
   final AnimatedString in1;
@@ -2549,8 +2625,19 @@
 
 @DocsEditable
 @DomName('SVGFETurbulenceElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FETurbulenceElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFETurbulenceElement" {
 
+  @DomName('SVGFETurbulenceElement.SVGFETurbulenceElement')
+  @DocsEditable
+  factory FETurbulenceElement() => _SvgElementFactoryProvider.createSvgElement_tag("feTurbulence");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('feTurbulence') && (new SvgElement.tag('feTurbulence') is FETurbulenceElement);
+
   static const int SVG_STITCHTYPE_NOSTITCH = 2;
 
   static const int SVG_STITCHTYPE_STITCH = 1;
@@ -2616,12 +2703,19 @@
 
 @DocsEditable
 @DomName('SVGFilterElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FilterElement extends StyledElement implements UriReference, ExternalResourcesRequired, LangSpace native "*SVGFilterElement" {
 
   @DomName('SVGFilterElement.SVGFilterElement')
   @DocsEditable
   factory FilterElement() => _SvgElementFactoryProvider.createSvgElement_tag("filter");
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('filter') && (new SvgElement.tag('filter') is FilterElement);
+
   @DomName('SVGFilterElement.filterResX')
   @DocsEditable
   final AnimatedInteger filterResX;
@@ -2716,91 +2810,19 @@
 
 
 @DocsEditable
-@DomName('SVGFontElement')
-class FontElement extends SvgElement native "*SVGFontElement" {
-
-  @DomName('SVGFontElement.SVGFontElement')
-  @DocsEditable
-  factory FontElement() => _SvgElementFactoryProvider.createSvgElement_tag("font");
-}
-// 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.
-
-
-@DocsEditable
-@DomName('SVGFontFaceElement')
-class FontFaceElement extends SvgElement native "*SVGFontFaceElement" {
-
-  @DomName('SVGFontFaceElement.SVGFontFaceElement')
-  @DocsEditable
-  factory FontFaceElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face");
-}
-// 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.
-
-
-@DocsEditable
-@DomName('SVGFontFaceFormatElement')
-class FontFaceFormatElement extends SvgElement native "*SVGFontFaceFormatElement" {
-
-  @DomName('SVGFontFaceFormatElement.SVGFontFaceFormatElement')
-  @DocsEditable
-  factory FontFaceFormatElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-format");
-}
-// 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.
-
-
-@DocsEditable
-@DomName('SVGFontFaceNameElement')
-class FontFaceNameElement extends SvgElement native "*SVGFontFaceNameElement" {
-
-  @DomName('SVGFontFaceNameElement.SVGFontFaceNameElement')
-  @DocsEditable
-  factory FontFaceNameElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-name");
-}
-// 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.
-
-
-@DocsEditable
-@DomName('SVGFontFaceSrcElement')
-class FontFaceSrcElement extends SvgElement native "*SVGFontFaceSrcElement" {
-
-  @DomName('SVGFontFaceSrcElement.SVGFontFaceSrcElement')
-  @DocsEditable
-  factory FontFaceSrcElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-src");
-}
-// 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.
-
-
-@DocsEditable
-@DomName('SVGFontFaceUriElement')
-class FontFaceUriElement extends SvgElement native "*SVGFontFaceUriElement" {
-
-  @DomName('SVGFontFaceUriElement.SVGFontFaceUriElement')
-  @DocsEditable
-  factory FontFaceUriElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-uri");
-}
-// 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.
-
-
-@DocsEditable
 @DomName('SVGForeignObjectElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class ForeignObjectElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGForeignObjectElement" {
 
   @DomName('SVGForeignObjectElement.SVGForeignObjectElement')
   @DocsEditable
   factory ForeignObjectElement() => _SvgElementFactoryProvider.createSvgElement_tag("foreignObject");
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('foreignObject') && (new SvgElement.tag('foreignObject') is ForeignObjectElement);
+
   @DomName('SVGForeignObjectElement.height')
   @DocsEditable
   final AnimatedLength height;
@@ -2972,112 +2994,6 @@
 
 
 @DocsEditable
-@DomName('SVGGlyphElement')
-class GlyphElement extends SvgElement native "*SVGGlyphElement" {
-
-  @DomName('SVGGlyphElement.SVGGlyphElement')
-  @DocsEditable
-  factory GlyphElement() => _SvgElementFactoryProvider.createSvgElement_tag("glyph");
-}
-// 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.
-
-
-@DocsEditable
-@DomName('SVGGlyphRefElement')
-class GlyphRefElement extends StyledElement implements UriReference native "*SVGGlyphRefElement" {
-
-  @DomName('SVGGlyphRefElement.dx')
-  @DocsEditable
-  num dx;
-
-  @DomName('SVGGlyphRefElement.dy')
-  @DocsEditable
-  num dy;
-
-  @DomName('SVGGlyphRefElement.format')
-  @DocsEditable
-  String format;
-
-  @DomName('SVGGlyphRefElement.glyphRef')
-  @DocsEditable
-  String glyphRef;
-
-  @DomName('SVGGlyphRefElement.x')
-  @DocsEditable
-  num x;
-
-  @DomName('SVGGlyphRefElement.y')
-  @DocsEditable
-  num y;
-
-  // From SVGURIReference
-
-  @DomName('SVGGlyphRefElement.href')
-  @DocsEditable
-  final AnimatedString href;
-}
-// 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.
-
-
-@DocsEditable
-@DomName('SVGGradientElement')
-class GradientElement extends StyledElement implements UriReference, ExternalResourcesRequired native "*SVGGradientElement" {
-
-  static const int SVG_SPREADMETHOD_PAD = 1;
-
-  static const int SVG_SPREADMETHOD_REFLECT = 2;
-
-  static const int SVG_SPREADMETHOD_REPEAT = 3;
-
-  static const int SVG_SPREADMETHOD_UNKNOWN = 0;
-
-  @DomName('SVGGradientElement.gradientTransform')
-  @DocsEditable
-  final AnimatedTransformList gradientTransform;
-
-  @DomName('SVGGradientElement.gradientUnits')
-  @DocsEditable
-  final AnimatedEnumeration gradientUnits;
-
-  @DomName('SVGGradientElement.spreadMethod')
-  @DocsEditable
-  final AnimatedEnumeration spreadMethod;
-
-  // From SVGExternalResourcesRequired
-
-  @DomName('SVGGradientElement.externalResourcesRequired')
-  @DocsEditable
-  final AnimatedBoolean externalResourcesRequired;
-
-  // From SVGURIReference
-
-  @DomName('SVGGradientElement.href')
-  @DocsEditable
-  final AnimatedString href;
-}
-// 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.
-
-
-@DocsEditable
-@DomName('SVGHKernElement')
-class HKernElement extends SvgElement native "*SVGHKernElement" {
-
-  @DomName('SVGHKernElement.SVGHKernElement')
-  @DocsEditable
-  factory HKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("hkern");
-}
-// 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.
-
-
-@DocsEditable
 @DomName('SVGImageElement')
 class ImageElement extends StyledElement implements UriReference, Tests, Transformable, ExternalResourcesRequired, LangSpace native "*SVGImageElement" {
 
@@ -3187,6 +3103,9 @@
 @DomName('SVGLangSpace')
 abstract class LangSpace {
 
+  /// Checks if this type is supported on the current platform.
+  static bool supported(SvgElement element) => JS('bool', '#.xmlspace !== undefined && #.xmllang !== undefined', element, element);
+
   String xmllang;
 
   String xmlspace;
@@ -3290,7 +3209,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Length element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Length element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -3571,7 +3490,7 @@
 
 @DocsEditable
 @DomName('SVGLinearGradientElement')
-class LinearGradientElement extends GradientElement native "*SVGLinearGradientElement" {
+class LinearGradientElement extends _SVGGradientElement native "*SVGLinearGradientElement" {
 
   @DomName('SVGLinearGradientElement.SVGLinearGradientElement')
   @DocsEditable
@@ -3619,31 +3538,6 @@
 
 
 @DocsEditable
-@DomName('SVGMPathElement')
-class MPathElement extends SvgElement implements UriReference, ExternalResourcesRequired native "*SVGMPathElement" {
-
-  @DomName('SVGMPathElement.SVGMPathElement')
-  @DocsEditable
-  factory MPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("mpath");
-
-  // From SVGExternalResourcesRequired
-
-  @DomName('SVGMPathElement.externalResourcesRequired')
-  @DocsEditable
-  final AnimatedBoolean externalResourcesRequired;
-
-  // From SVGURIReference
-
-  @DomName('SVGMPathElement.href')
-  @DocsEditable
-  final AnimatedString href;
-}
-// 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.
-
-
-@DocsEditable
 @DomName('SVGMarkerElement')
 class MarkerElement extends StyledElement implements FitToViewBox, ExternalResourcesRequired, LangSpace native "*SVGMarkerElement" {
 
@@ -3888,15 +3782,6 @@
 
 
 @DocsEditable
-@DomName('SVGMissingGlyphElement')
-class MissingGlyphElement extends StyledElement native "*SVGMissingGlyphElement" {
-}
-// 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.
-
-
-@DocsEditable
 @DomName('SVGNumber')
 class Number native "*SVGNumber" {
 
@@ -3948,7 +3833,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Number element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Number element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -4848,7 +4733,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(PathSeg element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(PathSeg element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -5442,7 +5327,7 @@
 
 @DocsEditable
 @DomName('SVGRadialGradientElement')
-class RadialGradientElement extends GradientElement native "*SVGRadialGradientElement" {
+class RadialGradientElement extends _SVGGradientElement native "*SVGRadialGradientElement" {
 
   @DomName('SVGRadialGradientElement.SVGRadialGradientElement')
   @DocsEditable
@@ -5659,11 +5544,17 @@
 
 @DocsEditable
 @DomName('SVGSetElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class SetElement extends AnimationElement native "*SVGSetElement" {
 
   @DomName('SVGSetElement.SVGSetElement')
   @DocsEditable
   factory SetElement() => _SvgElementFactoryProvider.createSvgElement_tag("set");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('set') && (new SvgElement.tag('set') is SetElement);
 }
 // 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
@@ -5726,7 +5617,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(String element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(String element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -6029,16 +5920,6 @@
     return _cssClassSet;
   }
 
-  @deprecated
-  List<Element> get elements => new FilteredElementList(this);
-
-  @deprecated
-  void set elements(Collection<Element> value) {
-    final elements = this.elements;
-    elements.clear();
-    elements.addAll(value);
-  }
-
   List<Element> get children => new FilteredElementList(this);
 
   void set children(List<Element> value) {
@@ -6095,6 +5976,15 @@
     throw new UnsupportedError("Cannot invoke click SVG.");
   }
 
+  /**
+   * Checks to see if the SVG element type is supported by the current platform.
+   *
+   * The tag should be a valid SVG element tag name.
+   */
+  static bool isTagSupported(String tag) {
+    var e = new SvgElement.tag(tag);
+    return e is SvgElement && !(e is UnknownElement);
+  }
 
   // Shadowing definition.
   String get id => JS("String", "#.id", this);
@@ -6533,25 +6423,6 @@
 
 
 @DocsEditable
-@DomName('SVGTRefElement')
-class TRefElement extends TextPositioningElement implements UriReference native "*SVGTRefElement" {
-
-  @DomName('SVGTRefElement.SVGTRefElement')
-  @DocsEditable
-  factory TRefElement() => _SvgElementFactoryProvider.createSvgElement_tag("tref");
-
-  // From SVGURIReference
-
-  @DomName('SVGTRefElement.href')
-  @DocsEditable
-  final AnimatedString href;
-}
-// 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.
-
-
-@DocsEditable
 @DomName('SVGTSpanElement')
 class TSpanElement extends TextPositioningElement native "*SVGTSpanElement" {
 
@@ -6909,7 +6780,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Transform element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Transform element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -7261,19 +7132,6 @@
 
 
 @DocsEditable
-@DomName('SVGVKernElement')
-class VKernElement extends SvgElement native "*SVGVKernElement" {
-
-  @DomName('SVGVKernElement.SVGVKernElement')
-  @DocsEditable
-  factory VKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("vkern");
-}
-// 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.
-
-
-@DocsEditable
 @DomName('SVGViewElement')
 class ViewElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired, ZoomAndPan native "*SVGViewElement" {
 
@@ -7439,7 +7297,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(ElementInstance element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(ElementInstance element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -7594,3 +7452,414 @@
   @DocsEditable
   ElementInstance item(int index) native;
 }
+// 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.
+
+
+@DocsEditable
+@DomName('SVGAltGlyphDefElement')
+class _SVGAltGlyphDefElement extends SvgElement native "*SVGAltGlyphDefElement" {
+}
+// 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.
+
+
+@DocsEditable
+@DomName('SVGAltGlyphItemElement')
+class _SVGAltGlyphItemElement extends SvgElement native "*SVGAltGlyphItemElement" {
+}
+// 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.
+
+
+@DocsEditable
+@DomName('SVGAnimateColorElement')
+class _SVGAnimateColorElement extends AnimationElement native "*SVGAnimateColorElement" {
+}
+// 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.
+
+
+@DocsEditable
+@DomName('SVGComponentTransferFunctionElement')
+class _SVGComponentTransferFunctionElement extends SvgElement native "*SVGComponentTransferFunctionElement" {
+
+  static const int SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE = 3;
+
+  static const int SVG_FECOMPONENTTRANSFER_TYPE_GAMMA = 5;
+
+  static const int SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY = 1;
+
+  static const int SVG_FECOMPONENTTRANSFER_TYPE_LINEAR = 4;
+
+  static const int SVG_FECOMPONENTTRANSFER_TYPE_TABLE = 2;
+
+  static const int SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN = 0;
+
+  @DomName('SVGComponentTransferFunctionElement.amplitude')
+  @DocsEditable
+  final AnimatedNumber amplitude;
+
+  @DomName('SVGComponentTransferFunctionElement.exponent')
+  @DocsEditable
+  final AnimatedNumber exponent;
+
+  @DomName('SVGComponentTransferFunctionElement.intercept')
+  @DocsEditable
+  final AnimatedNumber intercept;
+
+  @DomName('SVGComponentTransferFunctionElement.offset')
+  @DocsEditable
+  final AnimatedNumber offset;
+
+  @DomName('SVGComponentTransferFunctionElement.slope')
+  @DocsEditable
+  final AnimatedNumber slope;
+
+  @DomName('SVGComponentTransferFunctionElement.tableValues')
+  @DocsEditable
+  final AnimatedNumberList tableValues;
+
+  @DomName('SVGComponentTransferFunctionElement.type')
+  @DocsEditable
+  final AnimatedEnumeration type;
+}
+// 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.
+
+
+@DocsEditable
+@DomName('SVGCursorElement')
+class _SVGCursorElement extends SvgElement implements UriReference, Tests, ExternalResourcesRequired native "*SVGCursorElement" {
+
+  @DomName('SVGCursorElement.SVGCursorElement')
+  @DocsEditable
+  factory _SVGCursorElement() => _SvgElementFactoryProvider.createSvgElement_tag("cursor");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => SvgElement.isTagSupported('cursor') && (new SvgElement.tag('cursor') is _SVGCursorElement);
+
+  @DomName('SVGCursorElement.x')
+  @DocsEditable
+  final AnimatedLength x;
+
+  @DomName('SVGCursorElement.y')
+  @DocsEditable
+  final AnimatedLength y;
+
+  // From SVGExternalResourcesRequired
+
+  @DomName('SVGCursorElement.externalResourcesRequired')
+  @DocsEditable
+  final AnimatedBoolean externalResourcesRequired;
+
+  // From SVGTests
+
+  @DomName('SVGCursorElement.requiredExtensions')
+  @DocsEditable
+  final StringList requiredExtensions;
+
+  @DomName('SVGCursorElement.requiredFeatures')
+  @DocsEditable
+  final StringList requiredFeatures;
+
+  @DomName('SVGCursorElement.systemLanguage')
+  @DocsEditable
+  final StringList systemLanguage;
+
+  @DomName('SVGCursorElement.hasExtension')
+  @DocsEditable
+  bool hasExtension(String extension) native;
+
+  // From SVGURIReference
+
+  @DomName('SVGCursorElement.href')
+  @DocsEditable
+  final AnimatedString href;
+}
+// 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.
+
+
+@DocsEditable
+@DomName('SVGFEDropShadowElement')
+class _SVGFEDropShadowElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEDropShadowElement" {
+
+  @DomName('SVGFEDropShadowElement.dx')
+  @DocsEditable
+  final AnimatedNumber dx;
+
+  @DomName('SVGFEDropShadowElement.dy')
+  @DocsEditable
+  final AnimatedNumber dy;
+
+  @DomName('SVGFEDropShadowElement.in1')
+  @DocsEditable
+  final AnimatedString in1;
+
+  @DomName('SVGFEDropShadowElement.stdDeviationX')
+  @DocsEditable
+  final AnimatedNumber stdDeviationX;
+
+  @DomName('SVGFEDropShadowElement.stdDeviationY')
+  @DocsEditable
+  final AnimatedNumber stdDeviationY;
+
+  @DomName('SVGFEDropShadowElement.setStdDeviation')
+  @DocsEditable
+  void setStdDeviation(num stdDeviationX, num stdDeviationY) native;
+
+  // From SVGFilterPrimitiveStandardAttributes
+
+  @DomName('SVGFEDropShadowElement.height')
+  @DocsEditable
+  final AnimatedLength height;
+
+  @DomName('SVGFEDropShadowElement.result')
+  @DocsEditable
+  final AnimatedString result;
+
+  @DomName('SVGFEDropShadowElement.width')
+  @DocsEditable
+  final AnimatedLength width;
+
+  @DomName('SVGFEDropShadowElement.x')
+  @DocsEditable
+  final AnimatedLength x;
+
+  @DomName('SVGFEDropShadowElement.y')
+  @DocsEditable
+  final AnimatedLength y;
+}
+// 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.
+
+
+@DocsEditable
+@DomName('SVGFontElement')
+class _SVGFontElement extends SvgElement native "*SVGFontElement" {
+}
+// 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.
+
+
+@DocsEditable
+@DomName('SVGFontFaceElement')
+class _SVGFontFaceElement extends SvgElement native "*SVGFontFaceElement" {
+}
+// 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.
+
+
+@DocsEditable
+@DomName('SVGFontFaceFormatElement')
+class _SVGFontFaceFormatElement extends SvgElement native "*SVGFontFaceFormatElement" {
+}
+// 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.
+
+
+@DocsEditable
+@DomName('SVGFontFaceNameElement')
+class _SVGFontFaceNameElement extends SvgElement native "*SVGFontFaceNameElement" {
+}
+// 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.
+
+
+@DocsEditable
+@DomName('SVGFontFaceSrcElement')
+class _SVGFontFaceSrcElement extends SvgElement native "*SVGFontFaceSrcElement" {
+}
+// 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.
+
+
+@DocsEditable
+@DomName('SVGFontFaceUriElement')
+class _SVGFontFaceUriElement extends SvgElement native "*SVGFontFaceUriElement" {
+}
+// 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.
+
+
+@DocsEditable
+@DomName('SVGGlyphElement')
+class _SVGGlyphElement extends SvgElement native "*SVGGlyphElement" {
+
+  @DomName('SVGGlyphElement.SVGGlyphElement')
+  @DocsEditable
+  factory _SVGGlyphElement() => _SvgElementFactoryProvider.createSvgElement_tag("glyph");
+}
+// 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.
+
+
+@DocsEditable
+@DomName('SVGGlyphRefElement')
+class _SVGGlyphRefElement extends StyledElement implements UriReference native "*SVGGlyphRefElement" {
+
+  @DomName('SVGGlyphRefElement.dx')
+  @DocsEditable
+  num dx;
+
+  @DomName('SVGGlyphRefElement.dy')
+  @DocsEditable
+  num dy;
+
+  @DomName('SVGGlyphRefElement.format')
+  @DocsEditable
+  String format;
+
+  @DomName('SVGGlyphRefElement.glyphRef')
+  @DocsEditable
+  String glyphRef;
+
+  @DomName('SVGGlyphRefElement.x')
+  @DocsEditable
+  num x;
+
+  @DomName('SVGGlyphRefElement.y')
+  @DocsEditable
+  num y;
+
+  // From SVGURIReference
+
+  @DomName('SVGGlyphRefElement.href')
+  @DocsEditable
+  final AnimatedString href;
+}
+// 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.
+
+
+@DocsEditable
+@DomName('SVGGradientElement')
+class _SVGGradientElement extends StyledElement implements UriReference, ExternalResourcesRequired native "*SVGGradientElement" {
+
+  static const int SVG_SPREADMETHOD_PAD = 1;
+
+  static const int SVG_SPREADMETHOD_REFLECT = 2;
+
+  static const int SVG_SPREADMETHOD_REPEAT = 3;
+
+  static const int SVG_SPREADMETHOD_UNKNOWN = 0;
+
+  @DomName('SVGGradientElement.gradientTransform')
+  @DocsEditable
+  final AnimatedTransformList gradientTransform;
+
+  @DomName('SVGGradientElement.gradientUnits')
+  @DocsEditable
+  final AnimatedEnumeration gradientUnits;
+
+  @DomName('SVGGradientElement.spreadMethod')
+  @DocsEditable
+  final AnimatedEnumeration spreadMethod;
+
+  // From SVGExternalResourcesRequired
+
+  @DomName('SVGGradientElement.externalResourcesRequired')
+  @DocsEditable
+  final AnimatedBoolean externalResourcesRequired;
+
+  // From SVGURIReference
+
+  @DomName('SVGGradientElement.href')
+  @DocsEditable
+  final AnimatedString href;
+}
+// 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.
+
+
+@DocsEditable
+@DomName('SVGHKernElement')
+class _SVGHKernElement extends SvgElement native "*SVGHKernElement" {
+
+  @DomName('SVGHKernElement.SVGHKernElement')
+  @DocsEditable
+  factory _SVGHKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("hkern");
+}
+// 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.
+
+
+@DocsEditable
+@DomName('SVGMPathElement')
+class _SVGMPathElement extends SvgElement implements UriReference, ExternalResourcesRequired native "*SVGMPathElement" {
+
+  @DomName('SVGMPathElement.SVGMPathElement')
+  @DocsEditable
+  factory _SVGMPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("mpath");
+
+  // From SVGExternalResourcesRequired
+
+  @DomName('SVGMPathElement.externalResourcesRequired')
+  @DocsEditable
+  final AnimatedBoolean externalResourcesRequired;
+
+  // From SVGURIReference
+
+  @DomName('SVGMPathElement.href')
+  @DocsEditable
+  final AnimatedString href;
+}
+// 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.
+
+
+@DocsEditable
+@DomName('SVGMissingGlyphElement')
+class _SVGMissingGlyphElement extends StyledElement native "*SVGMissingGlyphElement" {
+}
+// 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.
+
+
+@DocsEditable
+@DomName('SVGTRefElement')
+class _SVGTRefElement extends TextPositioningElement implements UriReference native "*SVGTRefElement" {
+
+  @DomName('SVGTRefElement.SVGTRefElement')
+  @DocsEditable
+  factory _SVGTRefElement() => _SvgElementFactoryProvider.createSvgElement_tag("tref");
+
+  // From SVGURIReference
+
+  @DomName('SVGTRefElement.href')
+  @DocsEditable
+  final AnimatedString href;
+}
+// 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.
+
+
+@DocsEditable
+@DomName('SVGVKernElement')
+class _SVGVKernElement extends SvgElement native "*SVGVKernElement" {
+
+  @DomName('SVGVKernElement.SVGVKernElement')
+  @DocsEditable
+  factory _SVGVKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("vkern");
+}
diff --git a/sdk/lib/svg/dartium/svg_dartium.dart b/sdk/lib/svg/dartium/svg_dartium.dart
index 17a4b29..12ead7f 100644
--- a/sdk/lib/svg/dartium/svg_dartium.dart
+++ b/sdk/lib/svg/dartium/svg_dartium.dart
@@ -149,23 +149,20 @@
 
 
 @DocsEditable
-@DomName('SVGAltGlyphDefElement')
-class AltGlyphDefElement extends SvgElement {
-  AltGlyphDefElement.internal() : super.internal();
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
 @DomName('SVGAltGlyphElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class AltGlyphElement extends TextPositioningElement implements UriReference {
   AltGlyphElement.internal() : super.internal();
 
+  @DomName('SVGAltGlyphElement.SVGAltGlyphElement')
+  @DocsEditable
+  factory AltGlyphElement() => _SvgElementFactoryProvider.createSvgElement_tag("altGlyph");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('SVGAltGlyphElement.format')
   @DocsEditable
   String get format native "SVGAltGlyphElement_format_Getter";
@@ -195,19 +192,6 @@
 
 
 @DocsEditable
-@DomName('SVGAltGlyphItemElement')
-class AltGlyphItemElement extends SvgElement {
-  AltGlyphItemElement.internal() : super.internal();
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
 @DomName('SVGAngle')
 class Angle extends NativeFieldWrapperClass1 {
   Angle.internal();
@@ -267,24 +251,10 @@
 
 
 @DocsEditable
-@DomName('SVGAnimateColorElement')
-class AnimateColorElement extends AnimationElement {
-  AnimateColorElement.internal() : super.internal();
-
-  @DomName('SVGAnimateColorElement.SVGAnimateColorElement')
-  @DocsEditable
-  factory AnimateColorElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateColor");
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
 @DomName('SVGAnimateElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class AnimateElement extends AnimationElement {
   AnimateElement.internal() : super.internal();
 
@@ -292,6 +262,9 @@
   @DocsEditable
   factory AnimateElement() => _SvgElementFactoryProvider.createSvgElement_tag("animate");
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
 }
 // 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
@@ -302,6 +275,9 @@
 
 @DocsEditable
 @DomName('SVGAnimateMotionElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class AnimateMotionElement extends AnimationElement {
   AnimateMotionElement.internal() : super.internal();
 
@@ -309,6 +285,9 @@
   @DocsEditable
   factory AnimateMotionElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateMotion");
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
 }
 // 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
@@ -319,6 +298,9 @@
 
 @DocsEditable
 @DomName('SVGAnimateTransformElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class AnimateTransformElement extends AnimationElement {
   AnimateTransformElement.internal() : super.internal();
 
@@ -326,6 +308,9 @@
   @DocsEditable
   factory AnimateTransformElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateTransform");
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
 }
 // 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
@@ -895,108 +880,6 @@
 
 
 @DocsEditable
-@DomName('SVGComponentTransferFunctionElement')
-class ComponentTransferFunctionElement extends SvgElement {
-  ComponentTransferFunctionElement.internal() : super.internal();
-
-  static const int SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE = 3;
-
-  static const int SVG_FECOMPONENTTRANSFER_TYPE_GAMMA = 5;
-
-  static const int SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY = 1;
-
-  static const int SVG_FECOMPONENTTRANSFER_TYPE_LINEAR = 4;
-
-  static const int SVG_FECOMPONENTTRANSFER_TYPE_TABLE = 2;
-
-  static const int SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN = 0;
-
-  @DomName('SVGComponentTransferFunctionElement.amplitude')
-  @DocsEditable
-  AnimatedNumber get amplitude native "SVGComponentTransferFunctionElement_amplitude_Getter";
-
-  @DomName('SVGComponentTransferFunctionElement.exponent')
-  @DocsEditable
-  AnimatedNumber get exponent native "SVGComponentTransferFunctionElement_exponent_Getter";
-
-  @DomName('SVGComponentTransferFunctionElement.intercept')
-  @DocsEditable
-  AnimatedNumber get intercept native "SVGComponentTransferFunctionElement_intercept_Getter";
-
-  @DomName('SVGComponentTransferFunctionElement.offset')
-  @DocsEditable
-  AnimatedNumber get offset native "SVGComponentTransferFunctionElement_offset_Getter";
-
-  @DomName('SVGComponentTransferFunctionElement.slope')
-  @DocsEditable
-  AnimatedNumber get slope native "SVGComponentTransferFunctionElement_slope_Getter";
-
-  @DomName('SVGComponentTransferFunctionElement.tableValues')
-  @DocsEditable
-  AnimatedNumberList get tableValues native "SVGComponentTransferFunctionElement_tableValues_Getter";
-
-  @DomName('SVGComponentTransferFunctionElement.type')
-  @DocsEditable
-  AnimatedEnumeration get type native "SVGComponentTransferFunctionElement_type_Getter";
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
-@DomName('SVGCursorElement')
-class CursorElement extends SvgElement implements UriReference, Tests, ExternalResourcesRequired {
-  CursorElement.internal() : super.internal();
-
-  @DomName('SVGCursorElement.SVGCursorElement')
-  @DocsEditable
-  factory CursorElement() => _SvgElementFactoryProvider.createSvgElement_tag("cursor");
-
-  @DomName('SVGCursorElement.x')
-  @DocsEditable
-  AnimatedLength get x native "SVGCursorElement_x_Getter";
-
-  @DomName('SVGCursorElement.y')
-  @DocsEditable
-  AnimatedLength get y native "SVGCursorElement_y_Getter";
-
-  @DomName('SVGCursorElement.externalResourcesRequired')
-  @DocsEditable
-  AnimatedBoolean get externalResourcesRequired native "SVGCursorElement_externalResourcesRequired_Getter";
-
-  @DomName('SVGCursorElement.requiredExtensions')
-  @DocsEditable
-  StringList get requiredExtensions native "SVGCursorElement_requiredExtensions_Getter";
-
-  @DomName('SVGCursorElement.requiredFeatures')
-  @DocsEditable
-  StringList get requiredFeatures native "SVGCursorElement_requiredFeatures_Getter";
-
-  @DomName('SVGCursorElement.systemLanguage')
-  @DocsEditable
-  StringList get systemLanguage native "SVGCursorElement_systemLanguage_Getter";
-
-  @DomName('SVGCursorElement.hasExtension')
-  @DocsEditable
-  bool hasExtension(String extension) native "SVGCursorElement_hasExtension_Callback";
-
-  @DomName('SVGCursorElement.href')
-  @DocsEditable
-  AnimatedString get href native "SVGCursorElement_href_Getter";
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
 @DomName('SVGDefsElement')
 class DefsElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
   DefsElement.internal() : super.internal();
@@ -1115,163 +998,163 @@
 class ElementInstance extends EventTarget {
   ElementInstance.internal() : super.internal();
 
-  @DomName('SVGElementInstance.abort')
+  @DomName('SVGElementInstance.abortEvent')
   @DocsEditable
   static const EventStreamProvider<Event> abortEvent = const EventStreamProvider<Event>('abort');
 
-  @DomName('SVGElementInstance.beforecopy')
+  @DomName('SVGElementInstance.beforecopyEvent')
   @DocsEditable
   static const EventStreamProvider<Event> beforeCopyEvent = const EventStreamProvider<Event>('beforecopy');
 
-  @DomName('SVGElementInstance.beforecut')
+  @DomName('SVGElementInstance.beforecutEvent')
   @DocsEditable
   static const EventStreamProvider<Event> beforeCutEvent = const EventStreamProvider<Event>('beforecut');
 
-  @DomName('SVGElementInstance.beforepaste')
+  @DomName('SVGElementInstance.beforepasteEvent')
   @DocsEditable
   static const EventStreamProvider<Event> beforePasteEvent = const EventStreamProvider<Event>('beforepaste');
 
-  @DomName('SVGElementInstance.blur')
+  @DomName('SVGElementInstance.blurEvent')
   @DocsEditable
   static const EventStreamProvider<Event> blurEvent = const EventStreamProvider<Event>('blur');
 
-  @DomName('SVGElementInstance.change')
+  @DomName('SVGElementInstance.changeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');
 
-  @DomName('SVGElementInstance.click')
+  @DomName('SVGElementInstance.clickEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> clickEvent = const EventStreamProvider<MouseEvent>('click');
 
-  @DomName('SVGElementInstance.contextmenu')
+  @DomName('SVGElementInstance.contextmenuEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> contextMenuEvent = const EventStreamProvider<MouseEvent>('contextmenu');
 
-  @DomName('SVGElementInstance.copy')
+  @DomName('SVGElementInstance.copyEvent')
   @DocsEditable
   static const EventStreamProvider<Event> copyEvent = const EventStreamProvider<Event>('copy');
 
-  @DomName('SVGElementInstance.cut')
+  @DomName('SVGElementInstance.cutEvent')
   @DocsEditable
   static const EventStreamProvider<Event> cutEvent = const EventStreamProvider<Event>('cut');
 
-  @DomName('SVGElementInstance.dblclick')
+  @DomName('SVGElementInstance.dblclickEvent')
   @DocsEditable
   static const EventStreamProvider<Event> doubleClickEvent = const EventStreamProvider<Event>('dblclick');
 
-  @DomName('SVGElementInstance.drag')
+  @DomName('SVGElementInstance.dragEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragEvent = const EventStreamProvider<MouseEvent>('drag');
 
-  @DomName('SVGElementInstance.dragend')
+  @DomName('SVGElementInstance.dragendEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragEndEvent = const EventStreamProvider<MouseEvent>('dragend');
 
-  @DomName('SVGElementInstance.dragenter')
+  @DomName('SVGElementInstance.dragenterEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragEnterEvent = const EventStreamProvider<MouseEvent>('dragenter');
 
-  @DomName('SVGElementInstance.dragleave')
+  @DomName('SVGElementInstance.dragleaveEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragLeaveEvent = const EventStreamProvider<MouseEvent>('dragleave');
 
-  @DomName('SVGElementInstance.dragover')
+  @DomName('SVGElementInstance.dragoverEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragOverEvent = const EventStreamProvider<MouseEvent>('dragover');
 
-  @DomName('SVGElementInstance.dragstart')
+  @DomName('SVGElementInstance.dragstartEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dragStartEvent = const EventStreamProvider<MouseEvent>('dragstart');
 
-  @DomName('SVGElementInstance.drop')
+  @DomName('SVGElementInstance.dropEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> dropEvent = const EventStreamProvider<MouseEvent>('drop');
 
-  @DomName('SVGElementInstance.error')
+  @DomName('SVGElementInstance.errorEvent')
   @DocsEditable
   static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
 
-  @DomName('SVGElementInstance.focus')
+  @DomName('SVGElementInstance.focusEvent')
   @DocsEditable
   static const EventStreamProvider<Event> focusEvent = const EventStreamProvider<Event>('focus');
 
-  @DomName('SVGElementInstance.input')
+  @DomName('SVGElementInstance.inputEvent')
   @DocsEditable
   static const EventStreamProvider<Event> inputEvent = const EventStreamProvider<Event>('input');
 
-  @DomName('SVGElementInstance.keydown')
+  @DomName('SVGElementInstance.keydownEvent')
   @DocsEditable
   static const EventStreamProvider<KeyboardEvent> keyDownEvent = const EventStreamProvider<KeyboardEvent>('keydown');
 
-  @DomName('SVGElementInstance.keypress')
+  @DomName('SVGElementInstance.keypressEvent')
   @DocsEditable
   static const EventStreamProvider<KeyboardEvent> keyPressEvent = const EventStreamProvider<KeyboardEvent>('keypress');
 
-  @DomName('SVGElementInstance.keyup')
+  @DomName('SVGElementInstance.keyupEvent')
   @DocsEditable
   static const EventStreamProvider<KeyboardEvent> keyUpEvent = const EventStreamProvider<KeyboardEvent>('keyup');
 
-  @DomName('SVGElementInstance.load')
+  @DomName('SVGElementInstance.loadEvent')
   @DocsEditable
   static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');
 
-  @DomName('SVGElementInstance.mousedown')
+  @DomName('SVGElementInstance.mousedownEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> mouseDownEvent = const EventStreamProvider<MouseEvent>('mousedown');
 
-  @DomName('SVGElementInstance.mousemove')
+  @DomName('SVGElementInstance.mousemoveEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> mouseMoveEvent = const EventStreamProvider<MouseEvent>('mousemove');
 
-  @DomName('SVGElementInstance.mouseout')
+  @DomName('SVGElementInstance.mouseoutEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> mouseOutEvent = const EventStreamProvider<MouseEvent>('mouseout');
 
-  @DomName('SVGElementInstance.mouseover')
+  @DomName('SVGElementInstance.mouseoverEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> mouseOverEvent = const EventStreamProvider<MouseEvent>('mouseover');
 
-  @DomName('SVGElementInstance.mouseup')
+  @DomName('SVGElementInstance.mouseupEvent')
   @DocsEditable
   static const EventStreamProvider<MouseEvent> mouseUpEvent = const EventStreamProvider<MouseEvent>('mouseup');
 
-  @DomName('SVGElementInstance.mousewheel')
+  @DomName('SVGElementInstance.mousewheelEvent')
   @DocsEditable
   static const EventStreamProvider<WheelEvent> mouseWheelEvent = const EventStreamProvider<WheelEvent>('mousewheel');
 
-  @DomName('SVGElementInstance.paste')
+  @DomName('SVGElementInstance.pasteEvent')
   @DocsEditable
   static const EventStreamProvider<Event> pasteEvent = const EventStreamProvider<Event>('paste');
 
-  @DomName('SVGElementInstance.reset')
+  @DomName('SVGElementInstance.resetEvent')
   @DocsEditable
   static const EventStreamProvider<Event> resetEvent = const EventStreamProvider<Event>('reset');
 
-  @DomName('SVGElementInstance.resize')
+  @DomName('SVGElementInstance.resizeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');
 
-  @DomName('SVGElementInstance.scroll')
+  @DomName('SVGElementInstance.scrollEvent')
   @DocsEditable
   static const EventStreamProvider<Event> scrollEvent = const EventStreamProvider<Event>('scroll');
 
-  @DomName('SVGElementInstance.search')
+  @DomName('SVGElementInstance.searchEvent')
   @DocsEditable
   static const EventStreamProvider<Event> searchEvent = const EventStreamProvider<Event>('search');
 
-  @DomName('SVGElementInstance.select')
+  @DomName('SVGElementInstance.selectEvent')
   @DocsEditable
   static const EventStreamProvider<Event> selectEvent = const EventStreamProvider<Event>('select');
 
-  @DomName('SVGElementInstance.selectstart')
+  @DomName('SVGElementInstance.selectstartEvent')
   @DocsEditable
   static const EventStreamProvider<Event> selectStartEvent = const EventStreamProvider<Event>('selectstart');
 
-  @DomName('SVGElementInstance.submit')
+  @DomName('SVGElementInstance.submitEvent')
   @DocsEditable
   static const EventStreamProvider<Event> submitEvent = const EventStreamProvider<Event>('submit');
 
-  @DomName('SVGElementInstance.unload')
+  @DomName('SVGElementInstance.unloadEvent')
   @DocsEditable
   static const EventStreamProvider<Event> unloadEvent = const EventStreamProvider<Event>('unload');
 
@@ -1313,163 +1196,163 @@
   @DocsEditable
   ElementInstance get previousSibling native "SVGElementInstance_previousSibling_Getter";
 
-  @DomName('SVGElementInstance.abort')
+  @DomName('SVGElementInstance.onabort')
   @DocsEditable
   Stream<Event> get onAbort => abortEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.beforecopy')
+  @DomName('SVGElementInstance.onbeforecopy')
   @DocsEditable
   Stream<Event> get onBeforeCopy => beforeCopyEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.beforecut')
+  @DomName('SVGElementInstance.onbeforecut')
   @DocsEditable
   Stream<Event> get onBeforeCut => beforeCutEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.beforepaste')
+  @DomName('SVGElementInstance.onbeforepaste')
   @DocsEditable
   Stream<Event> get onBeforePaste => beforePasteEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.blur')
+  @DomName('SVGElementInstance.onblur')
   @DocsEditable
   Stream<Event> get onBlur => blurEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.change')
+  @DomName('SVGElementInstance.onchange')
   @DocsEditable
   Stream<Event> get onChange => changeEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.click')
+  @DomName('SVGElementInstance.onclick')
   @DocsEditable
   Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.contextmenu')
+  @DomName('SVGElementInstance.oncontextmenu')
   @DocsEditable
   Stream<MouseEvent> get onContextMenu => contextMenuEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.copy')
+  @DomName('SVGElementInstance.oncopy')
   @DocsEditable
   Stream<Event> get onCopy => copyEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.cut')
+  @DomName('SVGElementInstance.oncut')
   @DocsEditable
   Stream<Event> get onCut => cutEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.dblclick')
+  @DomName('SVGElementInstance.ondblclick')
   @DocsEditable
   Stream<Event> get onDoubleClick => doubleClickEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.drag')
+  @DomName('SVGElementInstance.ondrag')
   @DocsEditable
   Stream<MouseEvent> get onDrag => dragEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.dragend')
+  @DomName('SVGElementInstance.ondragend')
   @DocsEditable
   Stream<MouseEvent> get onDragEnd => dragEndEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.dragenter')
+  @DomName('SVGElementInstance.ondragenter')
   @DocsEditable
   Stream<MouseEvent> get onDragEnter => dragEnterEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.dragleave')
+  @DomName('SVGElementInstance.ondragleave')
   @DocsEditable
   Stream<MouseEvent> get onDragLeave => dragLeaveEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.dragover')
+  @DomName('SVGElementInstance.ondragover')
   @DocsEditable
   Stream<MouseEvent> get onDragOver => dragOverEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.dragstart')
+  @DomName('SVGElementInstance.ondragstart')
   @DocsEditable
   Stream<MouseEvent> get onDragStart => dragStartEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.drop')
+  @DomName('SVGElementInstance.ondrop')
   @DocsEditable
   Stream<MouseEvent> get onDrop => dropEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.error')
+  @DomName('SVGElementInstance.onerror')
   @DocsEditable
   Stream<Event> get onError => errorEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.focus')
+  @DomName('SVGElementInstance.onfocus')
   @DocsEditable
   Stream<Event> get onFocus => focusEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.input')
+  @DomName('SVGElementInstance.oninput')
   @DocsEditable
   Stream<Event> get onInput => inputEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.keydown')
+  @DomName('SVGElementInstance.onkeydown')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyDown => keyDownEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.keypress')
+  @DomName('SVGElementInstance.onkeypress')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyPress => keyPressEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.keyup')
+  @DomName('SVGElementInstance.onkeyup')
   @DocsEditable
   Stream<KeyboardEvent> get onKeyUp => keyUpEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.load')
+  @DomName('SVGElementInstance.onload')
   @DocsEditable
   Stream<Event> get onLoad => loadEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.mousedown')
+  @DomName('SVGElementInstance.onmousedown')
   @DocsEditable
   Stream<MouseEvent> get onMouseDown => mouseDownEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.mousemove')
+  @DomName('SVGElementInstance.onmousemove')
   @DocsEditable
   Stream<MouseEvent> get onMouseMove => mouseMoveEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.mouseout')
+  @DomName('SVGElementInstance.onmouseout')
   @DocsEditable
   Stream<MouseEvent> get onMouseOut => mouseOutEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.mouseover')
+  @DomName('SVGElementInstance.onmouseover')
   @DocsEditable
   Stream<MouseEvent> get onMouseOver => mouseOverEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.mouseup')
+  @DomName('SVGElementInstance.onmouseup')
   @DocsEditable
   Stream<MouseEvent> get onMouseUp => mouseUpEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.mousewheel')
+  @DomName('SVGElementInstance.onmousewheel')
   @DocsEditable
   Stream<WheelEvent> get onMouseWheel => mouseWheelEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.paste')
+  @DomName('SVGElementInstance.onpaste')
   @DocsEditable
   Stream<Event> get onPaste => pasteEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.reset')
+  @DomName('SVGElementInstance.onreset')
   @DocsEditable
   Stream<Event> get onReset => resetEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.resize')
+  @DomName('SVGElementInstance.onresize')
   @DocsEditable
   Stream<Event> get onResize => resizeEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.scroll')
+  @DomName('SVGElementInstance.onscroll')
   @DocsEditable
   Stream<Event> get onScroll => scrollEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.search')
+  @DomName('SVGElementInstance.onsearch')
   @DocsEditable
   Stream<Event> get onSearch => searchEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.select')
+  @DomName('SVGElementInstance.onselect')
   @DocsEditable
   Stream<Event> get onSelect => selectEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.selectstart')
+  @DomName('SVGElementInstance.onselectstart')
   @DocsEditable
   Stream<Event> get onSelectStart => selectStartEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.submit')
+  @DomName('SVGElementInstance.onsubmit')
   @DocsEditable
   Stream<Event> get onSubmit => submitEvent.forTarget(this);
 
-  @DomName('SVGElementInstance.unload')
+  @DomName('SVGElementInstance.onunload')
   @DocsEditable
   Stream<Event> get onUnload => unloadEvent.forTarget(this);
 
@@ -1739,6 +1622,9 @@
 class ExternalResourcesRequired extends NativeFieldWrapperClass1 {
   ExternalResourcesRequired.internal();
 
+  /// Checks if this type is supported on the current platform.
+  static bool supported(SvgElement element) => true;
+
   @DomName('SVGExternalResourcesRequired.externalResourcesRequired')
   @DocsEditable
   AnimatedBoolean get externalResourcesRequired native "SVGExternalResourcesRequired_externalResourcesRequired_Getter";
@@ -1753,9 +1639,20 @@
 
 @DocsEditable
 @DomName('SVGFEBlendElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEBlendElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEBlendElement.internal() : super.internal();
 
+  @DomName('SVGFEBlendElement.SVGFEBlendElement')
+  @DocsEditable
+  factory FEBlendElement() => _SvgElementFactoryProvider.createSvgElement_tag("feBlend");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   static const int SVG_FEBLEND_MODE_DARKEN = 4;
 
   static const int SVG_FEBLEND_MODE_LIGHTEN = 5;
@@ -1810,9 +1707,20 @@
 
 @DocsEditable
 @DomName('SVGFEColorMatrixElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEColorMatrixElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEColorMatrixElement.internal() : super.internal();
 
+  @DomName('SVGFEColorMatrixElement.SVGFEColorMatrixElement')
+  @DocsEditable
+  factory FEColorMatrixElement() => _SvgElementFactoryProvider.createSvgElement_tag("feColorMatrix");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   static const int SVG_FECOLORMATRIX_TYPE_HUEROTATE = 3;
 
   static const int SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA = 4;
@@ -1865,9 +1773,20 @@
 
 @DocsEditable
 @DomName('SVGFEComponentTransferElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEComponentTransferElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEComponentTransferElement.internal() : super.internal();
 
+  @DomName('SVGFEComponentTransferElement.SVGFEComponentTransferElement')
+  @DocsEditable
+  factory FEComponentTransferElement() => _SvgElementFactoryProvider.createSvgElement_tag("feComponentTransfer");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('SVGFEComponentTransferElement.in1')
   @DocsEditable
   AnimatedString get in1 native "SVGFEComponentTransferElement_in1_Getter";
@@ -1977,9 +1896,20 @@
 
 @DocsEditable
 @DomName('SVGFEConvolveMatrixElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEConvolveMatrixElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEConvolveMatrixElement.internal() : super.internal();
 
+  @DomName('SVGFEConvolveMatrixElement.SVGFEConvolveMatrixElement')
+  @DocsEditable
+  factory FEConvolveMatrixElement() => _SvgElementFactoryProvider.createSvgElement_tag("feConvolveMatrix");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   static const int SVG_EDGEMODE_DUPLICATE = 1;
 
   static const int SVG_EDGEMODE_NONE = 3;
@@ -2066,9 +1996,20 @@
 
 @DocsEditable
 @DomName('SVGFEDiffuseLightingElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEDiffuseLightingElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEDiffuseLightingElement.internal() : super.internal();
 
+  @DomName('SVGFEDiffuseLightingElement.SVGFEDiffuseLightingElement')
+  @DocsEditable
+  factory FEDiffuseLightingElement() => _SvgElementFactoryProvider.createSvgElement_tag("feDiffuseLighting");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('SVGFEDiffuseLightingElement.diffuseConstant')
   @DocsEditable
   AnimatedNumber get diffuseConstant native "SVGFEDiffuseLightingElement_diffuseConstant_Getter";
@@ -2119,9 +2060,20 @@
 
 @DocsEditable
 @DomName('SVGFEDisplacementMapElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEDisplacementMapElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEDisplacementMapElement.internal() : super.internal();
 
+  @DomName('SVGFEDisplacementMapElement.SVGFEDisplacementMapElement')
+  @DocsEditable
+  factory FEDisplacementMapElement() => _SvgElementFactoryProvider.createSvgElement_tag("feDisplacementMap");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   static const int SVG_CHANNEL_A = 4;
 
   static const int SVG_CHANNEL_B = 3;
@@ -2182,9 +2134,20 @@
 
 @DocsEditable
 @DomName('SVGFEDistantLightElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEDistantLightElement extends SvgElement {
   FEDistantLightElement.internal() : super.internal();
 
+  @DomName('SVGFEDistantLightElement.SVGFEDistantLightElement')
+  @DocsEditable
+  factory FEDistantLightElement() => _SvgElementFactoryProvider.createSvgElement_tag("feDistantLight");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('SVGFEDistantLightElement.azimuth')
   @DocsEditable
   AnimatedNumber get azimuth native "SVGFEDistantLightElement_azimuth_Getter";
@@ -2202,67 +2165,21 @@
 
 
 @DocsEditable
-@DomName('SVGFEDropShadowElement')
-class FEDropShadowElement extends StyledElement implements FilterPrimitiveStandardAttributes {
-  FEDropShadowElement.internal() : super.internal();
-
-  @DomName('SVGFEDropShadowElement.dx')
-  @DocsEditable
-  AnimatedNumber get dx native "SVGFEDropShadowElement_dx_Getter";
-
-  @DomName('SVGFEDropShadowElement.dy')
-  @DocsEditable
-  AnimatedNumber get dy native "SVGFEDropShadowElement_dy_Getter";
-
-  @DomName('SVGFEDropShadowElement.in1')
-  @DocsEditable
-  AnimatedString get in1 native "SVGFEDropShadowElement_in1_Getter";
-
-  @DomName('SVGFEDropShadowElement.stdDeviationX')
-  @DocsEditable
-  AnimatedNumber get stdDeviationX native "SVGFEDropShadowElement_stdDeviationX_Getter";
-
-  @DomName('SVGFEDropShadowElement.stdDeviationY')
-  @DocsEditable
-  AnimatedNumber get stdDeviationY native "SVGFEDropShadowElement_stdDeviationY_Getter";
-
-  @DomName('SVGFEDropShadowElement.setStdDeviation')
-  @DocsEditable
-  void setStdDeviation(num stdDeviationX, num stdDeviationY) native "SVGFEDropShadowElement_setStdDeviation_Callback";
-
-  @DomName('SVGFEDropShadowElement.height')
-  @DocsEditable
-  AnimatedLength get height native "SVGFEDropShadowElement_height_Getter";
-
-  @DomName('SVGFEDropShadowElement.result')
-  @DocsEditable
-  AnimatedString get result native "SVGFEDropShadowElement_result_Getter";
-
-  @DomName('SVGFEDropShadowElement.width')
-  @DocsEditable
-  AnimatedLength get width native "SVGFEDropShadowElement_width_Getter";
-
-  @DomName('SVGFEDropShadowElement.x')
-  @DocsEditable
-  AnimatedLength get x native "SVGFEDropShadowElement_x_Getter";
-
-  @DomName('SVGFEDropShadowElement.y')
-  @DocsEditable
-  AnimatedLength get y native "SVGFEDropShadowElement_y_Getter";
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
 @DomName('SVGFEFloodElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEFloodElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEFloodElement.internal() : super.internal();
 
+  @DomName('SVGFEFloodElement.SVGFEFloodElement')
+  @DocsEditable
+  factory FEFloodElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFlood");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('SVGFEFloodElement.height')
   @DocsEditable
   AnimatedLength get height native "SVGFEFloodElement_height_Getter";
@@ -2293,9 +2210,20 @@
 
 @DocsEditable
 @DomName('SVGFEFuncAElement')
-class FEFuncAElement extends ComponentTransferFunctionElement {
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+class FEFuncAElement extends _SVGComponentTransferFunctionElement {
   FEFuncAElement.internal() : super.internal();
 
+  @DomName('SVGFEFuncAElement.SVGFEFuncAElement')
+  @DocsEditable
+  factory FEFuncAElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncA");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
 }
 // 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
@@ -2306,9 +2234,20 @@
 
 @DocsEditable
 @DomName('SVGFEFuncBElement')
-class FEFuncBElement extends ComponentTransferFunctionElement {
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+class FEFuncBElement extends _SVGComponentTransferFunctionElement {
   FEFuncBElement.internal() : super.internal();
 
+  @DomName('SVGFEFuncBElement.SVGFEFuncBElement')
+  @DocsEditable
+  factory FEFuncBElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncB");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
 }
 // 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
@@ -2319,9 +2258,20 @@
 
 @DocsEditable
 @DomName('SVGFEFuncGElement')
-class FEFuncGElement extends ComponentTransferFunctionElement {
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+class FEFuncGElement extends _SVGComponentTransferFunctionElement {
   FEFuncGElement.internal() : super.internal();
 
+  @DomName('SVGFEFuncGElement.SVGFEFuncGElement')
+  @DocsEditable
+  factory FEFuncGElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncG");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
 }
 // 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
@@ -2332,9 +2282,20 @@
 
 @DocsEditable
 @DomName('SVGFEFuncRElement')
-class FEFuncRElement extends ComponentTransferFunctionElement {
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
+class FEFuncRElement extends _SVGComponentTransferFunctionElement {
   FEFuncRElement.internal() : super.internal();
 
+  @DomName('SVGFEFuncRElement.SVGFEFuncRElement')
+  @DocsEditable
+  factory FEFuncRElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncR");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
 }
 // 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
@@ -2345,9 +2306,20 @@
 
 @DocsEditable
 @DomName('SVGFEGaussianBlurElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEGaussianBlurElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEGaussianBlurElement.internal() : super.internal();
 
+  @DomName('SVGFEGaussianBlurElement.SVGFEGaussianBlurElement')
+  @DocsEditable
+  factory FEGaussianBlurElement() => _SvgElementFactoryProvider.createSvgElement_tag("feGaussianBlur");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('SVGFEGaussianBlurElement.in1')
   @DocsEditable
   AnimatedString get in1 native "SVGFEGaussianBlurElement_in1_Getter";
@@ -2394,9 +2366,20 @@
 
 @DocsEditable
 @DomName('SVGFEImageElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEImageElement extends StyledElement implements FilterPrimitiveStandardAttributes, UriReference, ExternalResourcesRequired, LangSpace {
   FEImageElement.internal() : super.internal();
 
+  @DomName('SVGFEImageElement.SVGFEImageElement')
+  @DocsEditable
+  factory FEImageElement() => _SvgElementFactoryProvider.createSvgElement_tag("feImage");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('SVGFEImageElement.preserveAspectRatio')
   @DocsEditable
   AnimatedPreserveAspectRatio get preserveAspectRatio native "SVGFEImageElement_preserveAspectRatio_Getter";
@@ -2455,9 +2438,20 @@
 
 @DocsEditable
 @DomName('SVGFEMergeElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEMergeElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEMergeElement.internal() : super.internal();
 
+  @DomName('SVGFEMergeElement.SVGFEMergeElement')
+  @DocsEditable
+  factory FEMergeElement() => _SvgElementFactoryProvider.createSvgElement_tag("feMerge");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('SVGFEMergeElement.height')
   @DocsEditable
   AnimatedLength get height native "SVGFEMergeElement_height_Getter";
@@ -2488,9 +2482,20 @@
 
 @DocsEditable
 @DomName('SVGFEMergeNodeElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEMergeNodeElement extends SvgElement {
   FEMergeNodeElement.internal() : super.internal();
 
+  @DomName('SVGFEMergeNodeElement.SVGFEMergeNodeElement')
+  @DocsEditable
+  factory FEMergeNodeElement() => _SvgElementFactoryProvider.createSvgElement_tag("feMergeNode");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('SVGFEMergeNodeElement.in1')
   @DocsEditable
   AnimatedString get in1 native "SVGFEMergeNodeElement_in1_Getter";
@@ -2564,9 +2569,20 @@
 
 @DocsEditable
 @DomName('SVGFEOffsetElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEOffsetElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEOffsetElement.internal() : super.internal();
 
+  @DomName('SVGFEOffsetElement.SVGFEOffsetElement')
+  @DocsEditable
+  factory FEOffsetElement() => _SvgElementFactoryProvider.createSvgElement_tag("feOffset");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('SVGFEOffsetElement.dx')
   @DocsEditable
   AnimatedNumber get dx native "SVGFEOffsetElement_dx_Getter";
@@ -2609,9 +2625,20 @@
 
 @DocsEditable
 @DomName('SVGFEPointLightElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FEPointLightElement extends SvgElement {
   FEPointLightElement.internal() : super.internal();
 
+  @DomName('SVGFEPointLightElement.SVGFEPointLightElement')
+  @DocsEditable
+  factory FEPointLightElement() => _SvgElementFactoryProvider.createSvgElement_tag("fePointLight");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('SVGFEPointLightElement.x')
   @DocsEditable
   AnimatedNumber get x native "SVGFEPointLightElement_x_Getter";
@@ -2634,9 +2661,20 @@
 
 @DocsEditable
 @DomName('SVGFESpecularLightingElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FESpecularLightingElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FESpecularLightingElement.internal() : super.internal();
 
+  @DomName('SVGFESpecularLightingElement.SVGFESpecularLightingElement')
+  @DocsEditable
+  factory FESpecularLightingElement() => _SvgElementFactoryProvider.createSvgElement_tag("feSpecularLighting");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('SVGFESpecularLightingElement.in1')
   @DocsEditable
   AnimatedString get in1 native "SVGFESpecularLightingElement_in1_Getter";
@@ -2683,9 +2721,20 @@
 
 @DocsEditable
 @DomName('SVGFESpotLightElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FESpotLightElement extends SvgElement {
   FESpotLightElement.internal() : super.internal();
 
+  @DomName('SVGFESpotLightElement.SVGFESpotLightElement')
+  @DocsEditable
+  factory FESpotLightElement() => _SvgElementFactoryProvider.createSvgElement_tag("feSpotLight");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('SVGFESpotLightElement.limitingConeAngle')
   @DocsEditable
   AnimatedNumber get limitingConeAngle native "SVGFESpotLightElement_limitingConeAngle_Getter";
@@ -2728,9 +2777,20 @@
 
 @DocsEditable
 @DomName('SVGFETileElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FETileElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FETileElement.internal() : super.internal();
 
+  @DomName('SVGFETileElement.SVGFETileElement')
+  @DocsEditable
+  factory FETileElement() => _SvgElementFactoryProvider.createSvgElement_tag("feTile");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('SVGFETileElement.in1')
   @DocsEditable
   AnimatedString get in1 native "SVGFETileElement_in1_Getter";
@@ -2765,9 +2825,20 @@
 
 @DocsEditable
 @DomName('SVGFETurbulenceElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FETurbulenceElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FETurbulenceElement.internal() : super.internal();
 
+  @DomName('SVGFETurbulenceElement.SVGFETurbulenceElement')
+  @DocsEditable
+  factory FETurbulenceElement() => _SvgElementFactoryProvider.createSvgElement_tag("feTurbulence");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   static const int SVG_STITCHTYPE_NOSTITCH = 2;
 
   static const int SVG_STITCHTYPE_STITCH = 1;
@@ -2834,6 +2905,10 @@
 
 @DocsEditable
 @DomName('SVGFilterElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.IE, '10')
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class FilterElement extends StyledElement implements UriReference, ExternalResourcesRequired, LangSpace {
   FilterElement.internal() : super.internal();
 
@@ -2841,6 +2916,9 @@
   @DocsEditable
   factory FilterElement() => _SvgElementFactoryProvider.createSvgElement_tag("filter");
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('SVGFilterElement.filterResX')
   @DocsEditable
   AnimatedInteger get filterResX native "SVGFilterElement_filterResX_Getter";
@@ -2964,109 +3042,10 @@
 
 
 @DocsEditable
-@DomName('SVGFontElement')
-class FontElement extends SvgElement {
-  FontElement.internal() : super.internal();
-
-  @DomName('SVGFontElement.SVGFontElement')
-  @DocsEditable
-  factory FontElement() => _SvgElementFactoryProvider.createSvgElement_tag("font");
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
-@DomName('SVGFontFaceElement')
-class FontFaceElement extends SvgElement {
-  FontFaceElement.internal() : super.internal();
-
-  @DomName('SVGFontFaceElement.SVGFontFaceElement')
-  @DocsEditable
-  factory FontFaceElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face");
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
-@DomName('SVGFontFaceFormatElement')
-class FontFaceFormatElement extends SvgElement {
-  FontFaceFormatElement.internal() : super.internal();
-
-  @DomName('SVGFontFaceFormatElement.SVGFontFaceFormatElement')
-  @DocsEditable
-  factory FontFaceFormatElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-format");
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
-@DomName('SVGFontFaceNameElement')
-class FontFaceNameElement extends SvgElement {
-  FontFaceNameElement.internal() : super.internal();
-
-  @DomName('SVGFontFaceNameElement.SVGFontFaceNameElement')
-  @DocsEditable
-  factory FontFaceNameElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-name");
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
-@DomName('SVGFontFaceSrcElement')
-class FontFaceSrcElement extends SvgElement {
-  FontFaceSrcElement.internal() : super.internal();
-
-  @DomName('SVGFontFaceSrcElement.SVGFontFaceSrcElement')
-  @DocsEditable
-  factory FontFaceSrcElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-src");
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
-@DomName('SVGFontFaceUriElement')
-class FontFaceUriElement extends SvgElement {
-  FontFaceUriElement.internal() : super.internal();
-
-  @DomName('SVGFontFaceUriElement.SVGFontFaceUriElement')
-  @DocsEditable
-  factory FontFaceUriElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-uri");
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
 @DomName('SVGForeignObjectElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class ForeignObjectElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
   ForeignObjectElement.internal() : super.internal();
 
@@ -3074,6 +3053,9 @@
   @DocsEditable
   factory ForeignObjectElement() => _SvgElementFactoryProvider.createSvgElement_tag("foreignObject");
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('SVGForeignObjectElement.height')
   @DocsEditable
   AnimatedLength get height native "SVGForeignObjectElement_height_Getter";
@@ -3244,146 +3226,6 @@
 
 
 @DocsEditable
-@DomName('SVGGlyphElement')
-class GlyphElement extends SvgElement {
-  GlyphElement.internal() : super.internal();
-
-  @DomName('SVGGlyphElement.SVGGlyphElement')
-  @DocsEditable
-  factory GlyphElement() => _SvgElementFactoryProvider.createSvgElement_tag("glyph");
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
-@DomName('SVGGlyphRefElement')
-class GlyphRefElement extends StyledElement implements UriReference {
-  GlyphRefElement.internal() : super.internal();
-
-  @DomName('SVGGlyphRefElement.dx')
-  @DocsEditable
-  num get dx native "SVGGlyphRefElement_dx_Getter";
-
-  @DomName('SVGGlyphRefElement.dx')
-  @DocsEditable
-  void set dx(num value) native "SVGGlyphRefElement_dx_Setter";
-
-  @DomName('SVGGlyphRefElement.dy')
-  @DocsEditable
-  num get dy native "SVGGlyphRefElement_dy_Getter";
-
-  @DomName('SVGGlyphRefElement.dy')
-  @DocsEditable
-  void set dy(num value) native "SVGGlyphRefElement_dy_Setter";
-
-  @DomName('SVGGlyphRefElement.format')
-  @DocsEditable
-  String get format native "SVGGlyphRefElement_format_Getter";
-
-  @DomName('SVGGlyphRefElement.format')
-  @DocsEditable
-  void set format(String value) native "SVGGlyphRefElement_format_Setter";
-
-  @DomName('SVGGlyphRefElement.glyphRef')
-  @DocsEditable
-  String get glyphRef native "SVGGlyphRefElement_glyphRef_Getter";
-
-  @DomName('SVGGlyphRefElement.glyphRef')
-  @DocsEditable
-  void set glyphRef(String value) native "SVGGlyphRefElement_glyphRef_Setter";
-
-  @DomName('SVGGlyphRefElement.x')
-  @DocsEditable
-  num get x native "SVGGlyphRefElement_x_Getter";
-
-  @DomName('SVGGlyphRefElement.x')
-  @DocsEditable
-  void set x(num value) native "SVGGlyphRefElement_x_Setter";
-
-  @DomName('SVGGlyphRefElement.y')
-  @DocsEditable
-  num get y native "SVGGlyphRefElement_y_Getter";
-
-  @DomName('SVGGlyphRefElement.y')
-  @DocsEditable
-  void set y(num value) native "SVGGlyphRefElement_y_Setter";
-
-  @DomName('SVGGlyphRefElement.href')
-  @DocsEditable
-  AnimatedString get href native "SVGGlyphRefElement_href_Getter";
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
-@DomName('SVGGradientElement')
-class GradientElement extends StyledElement implements UriReference, ExternalResourcesRequired {
-  GradientElement.internal() : super.internal();
-
-  static const int SVG_SPREADMETHOD_PAD = 1;
-
-  static const int SVG_SPREADMETHOD_REFLECT = 2;
-
-  static const int SVG_SPREADMETHOD_REPEAT = 3;
-
-  static const int SVG_SPREADMETHOD_UNKNOWN = 0;
-
-  @DomName('SVGGradientElement.gradientTransform')
-  @DocsEditable
-  AnimatedTransformList get gradientTransform native "SVGGradientElement_gradientTransform_Getter";
-
-  @DomName('SVGGradientElement.gradientUnits')
-  @DocsEditable
-  AnimatedEnumeration get gradientUnits native "SVGGradientElement_gradientUnits_Getter";
-
-  @DomName('SVGGradientElement.spreadMethod')
-  @DocsEditable
-  AnimatedEnumeration get spreadMethod native "SVGGradientElement_spreadMethod_Getter";
-
-  @DomName('SVGGradientElement.externalResourcesRequired')
-  @DocsEditable
-  AnimatedBoolean get externalResourcesRequired native "SVGGradientElement_externalResourcesRequired_Getter";
-
-  @DomName('SVGGradientElement.href')
-  @DocsEditable
-  AnimatedString get href native "SVGGradientElement_href_Getter";
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
-@DomName('SVGHKernElement')
-class HKernElement extends SvgElement {
-  HKernElement.internal() : super.internal();
-
-  @DomName('SVGHKernElement.SVGHKernElement')
-  @DocsEditable
-  factory HKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("hkern");
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
 @DomName('SVGImageElement')
 class ImageElement extends StyledElement implements UriReference, Tests, Transformable, ExternalResourcesRequired, LangSpace {
   ImageElement.internal() : super.internal();
@@ -3493,6 +3335,9 @@
 class LangSpace extends NativeFieldWrapperClass1 {
   LangSpace.internal();
 
+  /// Checks if this type is supported on the current platform.
+  static bool supported(SvgElement element) => true;
+
   @DomName('SVGLangSpace.xmllang')
   @DocsEditable
   String get xmllang native "SVGLangSpace_xmllang_Getter";
@@ -3628,7 +3473,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Length element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Length element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -3912,7 +3757,7 @@
 
 @DocsEditable
 @DomName('SVGLinearGradientElement')
-class LinearGradientElement extends GradientElement {
+class LinearGradientElement extends _SVGGradientElement {
   LinearGradientElement.internal() : super.internal();
 
   @DomName('SVGLinearGradientElement.SVGLinearGradientElement')
@@ -3981,31 +3826,6 @@
 
 
 @DocsEditable
-@DomName('SVGMPathElement')
-class MPathElement extends SvgElement implements UriReference, ExternalResourcesRequired {
-  MPathElement.internal() : super.internal();
-
-  @DomName('SVGMPathElement.SVGMPathElement')
-  @DocsEditable
-  factory MPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("mpath");
-
-  @DomName('SVGMPathElement.externalResourcesRequired')
-  @DocsEditable
-  AnimatedBoolean get externalResourcesRequired native "SVGMPathElement_externalResourcesRequired_Getter";
-
-  @DomName('SVGMPathElement.href')
-  @DocsEditable
-  AnimatedString get href native "SVGMPathElement_href_Getter";
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
 @DomName('SVGMarkerElement')
 class MarkerElement extends StyledElement implements FitToViewBox, ExternalResourcesRequired, LangSpace {
   MarkerElement.internal() : super.internal();
@@ -4294,19 +4114,6 @@
 
 
 @DocsEditable
-@DomName('SVGMissingGlyphElement')
-class MissingGlyphElement extends StyledElement {
-  MissingGlyphElement.internal() : super.internal();
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
 @DomName('SVGNumber')
 class Number extends NativeFieldWrapperClass1 {
   Number.internal();
@@ -4367,7 +4174,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Number element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Number element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -5544,7 +5351,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(PathSeg element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(PathSeg element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -6195,7 +6002,7 @@
 
 @DocsEditable
 @DomName('SVGRadialGradientElement')
-class RadialGradientElement extends GradientElement {
+class RadialGradientElement extends _SVGGradientElement {
   RadialGradientElement.internal() : super.internal();
 
   @DomName('SVGRadialGradientElement.SVGRadialGradientElement')
@@ -6444,6 +6251,9 @@
 
 @DocsEditable
 @DomName('SVGSetElement')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class SetElement extends AnimationElement {
   SetElement.internal() : super.internal();
 
@@ -6451,6 +6261,9 @@
   @DocsEditable
   factory SetElement() => _SvgElementFactoryProvider.createSvgElement_tag("set");
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
 }
 // 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
@@ -6520,7 +6333,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(String element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(String element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -6856,16 +6669,6 @@
     return _cssClassSet;
   }
 
-  @deprecated
-  List<Element> get elements => new FilteredElementList(this);
-
-  @deprecated
-  void set elements(Collection<Element> value) {
-    final elements = this.elements;
-    elements.clear();
-    elements.addAll(value);
-  }
-
   List<Element> get children => new FilteredElementList(this);
 
   void set children(List<Element> value) {
@@ -6922,6 +6725,15 @@
     throw new UnsupportedError("Cannot invoke click SVG.");
   }
 
+  /**
+   * Checks to see if the SVG element type is supported by the current platform.
+   *
+   * The tag should be a valid SVG element tag name.
+   */
+  static bool isTagSupported(String tag) {
+    var e = new SvgElement.tag(tag);
+    return e is SvgElement && !(e is UnknownElement);
+  }
   SvgElement.internal() : super.internal();
 
   @DomName('SVGElement.id')
@@ -7374,27 +7186,6 @@
 
 
 @DocsEditable
-@DomName('SVGTRefElement')
-class TRefElement extends TextPositioningElement implements UriReference {
-  TRefElement.internal() : super.internal();
-
-  @DomName('SVGTRefElement.SVGTRefElement')
-  @DocsEditable
-  factory TRefElement() => _SvgElementFactoryProvider.createSvgElement_tag("tref");
-
-  @DomName('SVGTRefElement.href')
-  @DocsEditable
-  AnimatedString get href native "SVGTRefElement_href_Getter";
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
 @DomName('SVGTSpanElement')
 class TSpanElement extends TextPositioningElement {
   TSpanElement.internal() : super.internal();
@@ -7794,7 +7585,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(Transform element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(Transform element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -8174,23 +7965,6 @@
 
 
 @DocsEditable
-@DomName('SVGVKernElement')
-class VKernElement extends SvgElement {
-  VKernElement.internal() : super.internal();
-
-  @DomName('SVGVKernElement.SVGVKernElement')
-  @DocsEditable
-  factory VKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("vkern");
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
 @DomName('SVGViewElement')
 class ViewElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired, ZoomAndPan {
   ViewElement.internal() : super.internal();
@@ -8382,7 +8156,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f(ElementInstance element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f(ElementInstance element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
@@ -8538,3 +8312,498 @@
   ElementInstance item(int index) native "SVGElementInstanceList_item_Callback";
 
 }
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('SVGAltGlyphDefElement')
+class _SVGAltGlyphDefElement extends SvgElement {
+  _SVGAltGlyphDefElement.internal() : super.internal();
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('SVGAltGlyphItemElement')
+class _SVGAltGlyphItemElement extends SvgElement {
+  _SVGAltGlyphItemElement.internal() : super.internal();
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('SVGAnimateColorElement')
+class _SVGAnimateColorElement extends AnimationElement {
+  _SVGAnimateColorElement.internal() : super.internal();
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('SVGComponentTransferFunctionElement')
+class _SVGComponentTransferFunctionElement extends SvgElement {
+  _SVGComponentTransferFunctionElement.internal() : super.internal();
+
+  static const int SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE = 3;
+
+  static const int SVG_FECOMPONENTTRANSFER_TYPE_GAMMA = 5;
+
+  static const int SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY = 1;
+
+  static const int SVG_FECOMPONENTTRANSFER_TYPE_LINEAR = 4;
+
+  static const int SVG_FECOMPONENTTRANSFER_TYPE_TABLE = 2;
+
+  static const int SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN = 0;
+
+  @DomName('SVGComponentTransferFunctionElement.amplitude')
+  @DocsEditable
+  AnimatedNumber get amplitude native "SVGComponentTransferFunctionElement_amplitude_Getter";
+
+  @DomName('SVGComponentTransferFunctionElement.exponent')
+  @DocsEditable
+  AnimatedNumber get exponent native "SVGComponentTransferFunctionElement_exponent_Getter";
+
+  @DomName('SVGComponentTransferFunctionElement.intercept')
+  @DocsEditable
+  AnimatedNumber get intercept native "SVGComponentTransferFunctionElement_intercept_Getter";
+
+  @DomName('SVGComponentTransferFunctionElement.offset')
+  @DocsEditable
+  AnimatedNumber get offset native "SVGComponentTransferFunctionElement_offset_Getter";
+
+  @DomName('SVGComponentTransferFunctionElement.slope')
+  @DocsEditable
+  AnimatedNumber get slope native "SVGComponentTransferFunctionElement_slope_Getter";
+
+  @DomName('SVGComponentTransferFunctionElement.tableValues')
+  @DocsEditable
+  AnimatedNumberList get tableValues native "SVGComponentTransferFunctionElement_tableValues_Getter";
+
+  @DomName('SVGComponentTransferFunctionElement.type')
+  @DocsEditable
+  AnimatedEnumeration get type native "SVGComponentTransferFunctionElement_type_Getter";
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('SVGCursorElement')
+class _SVGCursorElement extends SvgElement implements UriReference, Tests, ExternalResourcesRequired {
+  _SVGCursorElement.internal() : super.internal();
+
+  @DomName('SVGCursorElement.SVGCursorElement')
+  @DocsEditable
+  factory _SVGCursorElement() => _SvgElementFactoryProvider.createSvgElement_tag("cursor");
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
+  @DomName('SVGCursorElement.x')
+  @DocsEditable
+  AnimatedLength get x native "SVGCursorElement_x_Getter";
+
+  @DomName('SVGCursorElement.y')
+  @DocsEditable
+  AnimatedLength get y native "SVGCursorElement_y_Getter";
+
+  @DomName('SVGCursorElement.externalResourcesRequired')
+  @DocsEditable
+  AnimatedBoolean get externalResourcesRequired native "SVGCursorElement_externalResourcesRequired_Getter";
+
+  @DomName('SVGCursorElement.requiredExtensions')
+  @DocsEditable
+  StringList get requiredExtensions native "SVGCursorElement_requiredExtensions_Getter";
+
+  @DomName('SVGCursorElement.requiredFeatures')
+  @DocsEditable
+  StringList get requiredFeatures native "SVGCursorElement_requiredFeatures_Getter";
+
+  @DomName('SVGCursorElement.systemLanguage')
+  @DocsEditable
+  StringList get systemLanguage native "SVGCursorElement_systemLanguage_Getter";
+
+  @DomName('SVGCursorElement.hasExtension')
+  @DocsEditable
+  bool hasExtension(String extension) native "SVGCursorElement_hasExtension_Callback";
+
+  @DomName('SVGCursorElement.href')
+  @DocsEditable
+  AnimatedString get href native "SVGCursorElement_href_Getter";
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('SVGFEDropShadowElement')
+class _SVGFEDropShadowElement extends StyledElement implements FilterPrimitiveStandardAttributes {
+  _SVGFEDropShadowElement.internal() : super.internal();
+
+  @DomName('SVGFEDropShadowElement.dx')
+  @DocsEditable
+  AnimatedNumber get dx native "SVGFEDropShadowElement_dx_Getter";
+
+  @DomName('SVGFEDropShadowElement.dy')
+  @DocsEditable
+  AnimatedNumber get dy native "SVGFEDropShadowElement_dy_Getter";
+
+  @DomName('SVGFEDropShadowElement.in1')
+  @DocsEditable
+  AnimatedString get in1 native "SVGFEDropShadowElement_in1_Getter";
+
+  @DomName('SVGFEDropShadowElement.stdDeviationX')
+  @DocsEditable
+  AnimatedNumber get stdDeviationX native "SVGFEDropShadowElement_stdDeviationX_Getter";
+
+  @DomName('SVGFEDropShadowElement.stdDeviationY')
+  @DocsEditable
+  AnimatedNumber get stdDeviationY native "SVGFEDropShadowElement_stdDeviationY_Getter";
+
+  @DomName('SVGFEDropShadowElement.setStdDeviation')
+  @DocsEditable
+  void setStdDeviation(num stdDeviationX, num stdDeviationY) native "SVGFEDropShadowElement_setStdDeviation_Callback";
+
+  @DomName('SVGFEDropShadowElement.height')
+  @DocsEditable
+  AnimatedLength get height native "SVGFEDropShadowElement_height_Getter";
+
+  @DomName('SVGFEDropShadowElement.result')
+  @DocsEditable
+  AnimatedString get result native "SVGFEDropShadowElement_result_Getter";
+
+  @DomName('SVGFEDropShadowElement.width')
+  @DocsEditable
+  AnimatedLength get width native "SVGFEDropShadowElement_width_Getter";
+
+  @DomName('SVGFEDropShadowElement.x')
+  @DocsEditable
+  AnimatedLength get x native "SVGFEDropShadowElement_x_Getter";
+
+  @DomName('SVGFEDropShadowElement.y')
+  @DocsEditable
+  AnimatedLength get y native "SVGFEDropShadowElement_y_Getter";
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('SVGFontElement')
+class _SVGFontElement extends SvgElement {
+  _SVGFontElement.internal() : super.internal();
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('SVGFontFaceElement')
+class _SVGFontFaceElement extends SvgElement {
+  _SVGFontFaceElement.internal() : super.internal();
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('SVGFontFaceFormatElement')
+class _SVGFontFaceFormatElement extends SvgElement {
+  _SVGFontFaceFormatElement.internal() : super.internal();
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('SVGFontFaceNameElement')
+class _SVGFontFaceNameElement extends SvgElement {
+  _SVGFontFaceNameElement.internal() : super.internal();
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('SVGFontFaceSrcElement')
+class _SVGFontFaceSrcElement extends SvgElement {
+  _SVGFontFaceSrcElement.internal() : super.internal();
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('SVGFontFaceUriElement')
+class _SVGFontFaceUriElement extends SvgElement {
+  _SVGFontFaceUriElement.internal() : super.internal();
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('SVGGlyphElement')
+class _SVGGlyphElement extends SvgElement {
+  _SVGGlyphElement.internal() : super.internal();
+
+  @DomName('SVGGlyphElement.SVGGlyphElement')
+  @DocsEditable
+  factory _SVGGlyphElement() => _SvgElementFactoryProvider.createSvgElement_tag("glyph");
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('SVGGlyphRefElement')
+class _SVGGlyphRefElement extends StyledElement implements UriReference {
+  _SVGGlyphRefElement.internal() : super.internal();
+
+  @DomName('SVGGlyphRefElement.dx')
+  @DocsEditable
+  num get dx native "SVGGlyphRefElement_dx_Getter";
+
+  @DomName('SVGGlyphRefElement.dx')
+  @DocsEditable
+  void set dx(num value) native "SVGGlyphRefElement_dx_Setter";
+
+  @DomName('SVGGlyphRefElement.dy')
+  @DocsEditable
+  num get dy native "SVGGlyphRefElement_dy_Getter";
+
+  @DomName('SVGGlyphRefElement.dy')
+  @DocsEditable
+  void set dy(num value) native "SVGGlyphRefElement_dy_Setter";
+
+  @DomName('SVGGlyphRefElement.format')
+  @DocsEditable
+  String get format native "SVGGlyphRefElement_format_Getter";
+
+  @DomName('SVGGlyphRefElement.format')
+  @DocsEditable
+  void set format(String value) native "SVGGlyphRefElement_format_Setter";
+
+  @DomName('SVGGlyphRefElement.glyphRef')
+  @DocsEditable
+  String get glyphRef native "SVGGlyphRefElement_glyphRef_Getter";
+
+  @DomName('SVGGlyphRefElement.glyphRef')
+  @DocsEditable
+  void set glyphRef(String value) native "SVGGlyphRefElement_glyphRef_Setter";
+
+  @DomName('SVGGlyphRefElement.x')
+  @DocsEditable
+  num get x native "SVGGlyphRefElement_x_Getter";
+
+  @DomName('SVGGlyphRefElement.x')
+  @DocsEditable
+  void set x(num value) native "SVGGlyphRefElement_x_Setter";
+
+  @DomName('SVGGlyphRefElement.y')
+  @DocsEditable
+  num get y native "SVGGlyphRefElement_y_Getter";
+
+  @DomName('SVGGlyphRefElement.y')
+  @DocsEditable
+  void set y(num value) native "SVGGlyphRefElement_y_Setter";
+
+  @DomName('SVGGlyphRefElement.href')
+  @DocsEditable
+  AnimatedString get href native "SVGGlyphRefElement_href_Getter";
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('SVGGradientElement')
+class _SVGGradientElement extends StyledElement implements UriReference, ExternalResourcesRequired {
+  _SVGGradientElement.internal() : super.internal();
+
+  static const int SVG_SPREADMETHOD_PAD = 1;
+
+  static const int SVG_SPREADMETHOD_REFLECT = 2;
+
+  static const int SVG_SPREADMETHOD_REPEAT = 3;
+
+  static const int SVG_SPREADMETHOD_UNKNOWN = 0;
+
+  @DomName('SVGGradientElement.gradientTransform')
+  @DocsEditable
+  AnimatedTransformList get gradientTransform native "SVGGradientElement_gradientTransform_Getter";
+
+  @DomName('SVGGradientElement.gradientUnits')
+  @DocsEditable
+  AnimatedEnumeration get gradientUnits native "SVGGradientElement_gradientUnits_Getter";
+
+  @DomName('SVGGradientElement.spreadMethod')
+  @DocsEditable
+  AnimatedEnumeration get spreadMethod native "SVGGradientElement_spreadMethod_Getter";
+
+  @DomName('SVGGradientElement.externalResourcesRequired')
+  @DocsEditable
+  AnimatedBoolean get externalResourcesRequired native "SVGGradientElement_externalResourcesRequired_Getter";
+
+  @DomName('SVGGradientElement.href')
+  @DocsEditable
+  AnimatedString get href native "SVGGradientElement_href_Getter";
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('SVGHKernElement')
+class _SVGHKernElement extends SvgElement {
+  _SVGHKernElement.internal() : super.internal();
+
+  @DomName('SVGHKernElement.SVGHKernElement')
+  @DocsEditable
+  factory _SVGHKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("hkern");
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('SVGMPathElement')
+class _SVGMPathElement extends SvgElement implements UriReference, ExternalResourcesRequired {
+  _SVGMPathElement.internal() : super.internal();
+
+  @DomName('SVGMPathElement.SVGMPathElement')
+  @DocsEditable
+  factory _SVGMPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("mpath");
+
+  @DomName('SVGMPathElement.externalResourcesRequired')
+  @DocsEditable
+  AnimatedBoolean get externalResourcesRequired native "SVGMPathElement_externalResourcesRequired_Getter";
+
+  @DomName('SVGMPathElement.href')
+  @DocsEditable
+  AnimatedString get href native "SVGMPathElement_href_Getter";
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('SVGMissingGlyphElement')
+class _SVGMissingGlyphElement extends StyledElement {
+  _SVGMissingGlyphElement.internal() : super.internal();
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('SVGTRefElement')
+class _SVGTRefElement extends TextPositioningElement implements UriReference {
+  _SVGTRefElement.internal() : super.internal();
+
+  @DomName('SVGTRefElement.SVGTRefElement')
+  @DocsEditable
+  factory _SVGTRefElement() => _SvgElementFactoryProvider.createSvgElement_tag("tref");
+
+  @DomName('SVGTRefElement.href')
+  @DocsEditable
+  AnimatedString get href native "SVGTRefElement_href_Getter";
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('SVGVKernElement')
+class _SVGVKernElement extends SvgElement {
+  _SVGVKernElement.internal() : super.internal();
+
+  @DomName('SVGVKernElement.SVGVKernElement')
+  @DocsEditable
+  factory _SVGVKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("vkern");
+
+}
diff --git a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
index 5042795..6857253 100644
--- a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
+++ b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
@@ -176,7 +176,7 @@
 @DomName('AudioContext')
 class AudioContext extends EventTarget native "*AudioContext" {
 
-  @DomName('AudioContext.complete')
+  @DomName('AudioContext.completeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> completeEvent = const EventStreamProvider<Event>('complete');
 
@@ -278,7 +278,7 @@
   @DocsEditable
   void startRendering() native;
 
-  @DomName('AudioContext.complete')
+  @DomName('AudioContext.oncomplete')
   @DocsEditable
   Stream<Event> get onComplete => completeEvent.forTarget(this);
 
diff --git a/sdk/lib/web_audio/dartium/web_audio_dartium.dart b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
index ec52898..765c957 100644
--- a/sdk/lib/web_audio/dartium/web_audio_dartium.dart
+++ b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
@@ -227,7 +227,7 @@
 class AudioContext extends EventTarget {
   AudioContext.internal() : super.internal();
 
-  @DomName('AudioContext.complete')
+  @DomName('AudioContext.completeEvent')
   @DocsEditable
   static const EventStreamProvider<Event> completeEvent = const EventStreamProvider<Event>('complete');
   factory AudioContext() => _create();
@@ -406,7 +406,7 @@
   @DocsEditable
   void startRendering() native "AudioContext_startRendering_Callback";
 
-  @DomName('AudioContext.complete')
+  @DomName('AudioContext.oncomplete')
   @DocsEditable
   Stream<Event> get onComplete => completeEvent.forTarget(this);
 
diff --git a/tests/compiler/dart2js/call_site_type_inferer_test.dart b/tests/compiler/dart2js/call_site_type_inferer_test.dart
index a220063..c868f4b 100644
--- a/tests/compiler/dart2js/call_site_type_inferer_test.dart
+++ b/tests/compiler/dart2js/call_site_type_inferer_test.dart
@@ -138,7 +138,7 @@
   f(p) => p.x(2.2);
   main() {
     new A().x(1);
-    f(null);
+    f(new A());
   }
 """;
 
@@ -190,6 +190,18 @@
   }
 """;
 
+const String TEST_18 = r"""
+  class A {
+    x(p1, p2) => x(p1, p2);
+  }
+  class B extends A {
+  }
+  main() {
+    new B().x("a", "b");
+    new A().x(1, 2);
+  }
+""";
+
 void doTest(String test,
             bool enableInlining,
             List<HType> expectedTypes,
@@ -229,7 +241,7 @@
   runTest(TEST_7);
   runTest(TEST_8, [HType.INTEGER, HType.UNKNOWN]);
   runTest(TEST_9, [HType.INTEGER, HType.INTEGER]);
-  runTest(TEST_10);
+  runTest(TEST_10, [HType.INTEGER, HType.INTEGER]);
   runTest(TEST_11);
 
   defaultTypes = new OptionalParameterTypes(1);
@@ -255,6 +267,8 @@
   defaultTypes.update(0, const SourceString("p2"), HType.INTEGER);
   defaultTypes.update(1, const SourceString("p3"), HType.STRING);
   runTest(TEST_17, [HType.INTEGER, HType.BOOLEAN, HType.DOUBLE], defaultTypes);
+
+  runTest(TEST_18);
 }
 
 void main() {
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index 498e3ee..153df18 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -6,9 +6,11 @@
 constant_folding_string_test: Fail
 tree_shaking_test: Fail # Issue 4811
 boolified_operator_test: Fail # Issue 8001
+analyze_api_test: Pass, Slow
 
 [ $checked ]
 field_type_inferer_test: Slow, Pass # Issue 6658.
 
 [ $jscl || $runtime == drt || $runtime == dartium || $runtime == ff || $runtime == firefox || $runtime == chrome || $runtime == safari || $runtime == ie9 || $runtime == opera ]
 *: Skip # dart2js uses #import('dart:io'); and it is not self-hosted (yet).
+
diff --git a/tests/compiler/dart2js/type_combination_test.dart b/tests/compiler/dart2js/type_combination_test.dart
index 2f5c030..5633b90 100644
--- a/tests/compiler/dart2js/type_combination_test.dart
+++ b/tests/compiler/dart2js/type_combination_test.dart
@@ -431,7 +431,7 @@
                 READABLE_ARRAY.union(DOUBLE_OR_NULL, compiler));
   Expect.equals(UNKNOWN, 
                 READABLE_ARRAY.union(STRING_OR_NULL, compiler));
-  Expect.equals(UNKNOWN, 
+  Expect.equals(potentialArray, 
                 READABLE_ARRAY.union(NULL, compiler));
   Expect.equals(READABLE_ARRAY, 
                 READABLE_ARRAY.union(FIXED_ARRAY, compiler));
@@ -476,7 +476,7 @@
                 MUTABLE_ARRAY.union(DOUBLE_OR_NULL, compiler));
   Expect.equals(UNKNOWN, 
                 MUTABLE_ARRAY.union(STRING_OR_NULL, compiler));
-  Expect.equals(UNKNOWN, 
+  Expect.equals(potentialArray, 
                 MUTABLE_ARRAY.union(NULL, compiler));
   Expect.equals(MUTABLE_ARRAY, 
                 MUTABLE_ARRAY.union(FIXED_ARRAY, compiler));
@@ -521,7 +521,7 @@
                 EXTENDABLE_ARRAY.union(DOUBLE_OR_NULL, compiler));
   Expect.equals(UNKNOWN, 
                 EXTENDABLE_ARRAY.union(STRING_OR_NULL, compiler));
-  Expect.equals(UNKNOWN, 
+  Expect.equals(potentialArray, 
                 EXTENDABLE_ARRAY.union(NULL, compiler));
   Expect.equals(MUTABLE_ARRAY, 
                 EXTENDABLE_ARRAY.union(FIXED_ARRAY, compiler));
@@ -945,11 +945,11 @@
                 NULL.union(INDEXABLE_PRIMITIVE, compiler));
   Expect.equals(STRING_OR_NULL, 
                 NULL.union(STRING, compiler));
-  Expect.equals(UNKNOWN, 
+  Expect.equals(potentialArray, 
                 NULL.union(READABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN, 
+  Expect.equals(potentialArray, 
                 NULL.union(MUTABLE_ARRAY, compiler));
-  Expect.equals(UNKNOWN, 
+  Expect.equals(potentialArray, 
                 NULL.union(EXTENDABLE_ARRAY, compiler));
   Expect.equals(UNKNOWN, 
                 NULL.union(nonPrimitive1, compiler));
@@ -971,7 +971,7 @@
                 NULL.union(STRING_OR_NULL, compiler));
   Expect.equals(NULL, 
                 NULL.union(NULL, compiler));
-  Expect.equals(UNKNOWN, 
+  Expect.equals(potentialArray, 
                 NULL.union(FIXED_ARRAY, compiler));
 
   Expect.equals(FIXED_ARRAY, 
@@ -1014,7 +1014,7 @@
                 FIXED_ARRAY.union(DOUBLE_OR_NULL, compiler));
   Expect.equals(UNKNOWN, 
                 FIXED_ARRAY.union(STRING_OR_NULL, compiler));
-  Expect.equals(UNKNOWN, 
+  Expect.equals(potentialArray, 
                 FIXED_ARRAY.union(NULL, compiler));
   Expect.equals(FIXED_ARRAY, 
                 FIXED_ARRAY.union(FIXED_ARRAY, compiler));
diff --git a/tests/html/element_types_test.dart b/tests/html/element_types_test.dart
index 9ef2449..f681bd0 100644
--- a/tests/html/element_types_test.dart
+++ b/tests/html/element_types_test.dart
@@ -48,7 +48,7 @@
 
   group('supported_object', () {
     test('supported', () {
-      expect(MeterElement.supported, true);
+      expect(ObjectElement.supported, true);
     });
   });
 
diff --git a/tests/html/html.status b/tests/html/html.status
index 1853065..7730ee7 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -59,7 +59,6 @@
 element_types_test/supported_details: Fail
 element_types_test/supported_keygen: Fail
 element_types_test/supported_meter: Fail
-element_types_test/supported_object: Fail
 element_types_test/supported_output: Fail
 element_types_test/supported_shadow: Fail
 form_data_test: Fail # TODO(efortuna): Issue 7875.
@@ -86,8 +85,12 @@
 shadow_dom_test/supported: Fail
 speechrecognition_test/supported: Fail
 storage_test: Fail, Pass
-svgelement_test/additionalConstructors: Fail
-svgelement2_test: Fail
+svgelement_test/supported_altGlyph: Fail
+svgelement_test/supported_animate: Fail
+svgelement_test/supported_animateTransform: Fail
+svgelement_test/supported_animateMotion: Fail
+svgelement_test/supported_foreignObject: Fail
+svgelement_test/supported_set: Fail
 touchevent_test/supported: Fail
 webgl_1_test/supported: Fail
 websql_test/supported: Fail
@@ -107,7 +110,6 @@
 element_types_test/supported_details: Fail
 element_types_test/supported_keygen: Fail
 element_types_test/supported_meter: Fail
-element_types_test/supported_object: Fail
 element_types_test/supported_output: Fail
 element_types_test/supported_progress: Fail
 element_types_test/supported_shadow: Fail
@@ -119,6 +121,9 @@
 localstorage_test: Fail
 webgl_1_test/supported: Fail
 websql_test/supported: Fail
+
+microtask_test: Pass, Fail # http://dartbug.com/8300
+
 #
 # Investigate and triage the following into bug reports.
 #
@@ -156,9 +161,36 @@
 serialized_script_value_test: Fail
 shadow_dom_test/supported: Fail
 speechrecognition_test/supported: Fail
-svg_3_test: Fail
-svgelement_test/additionalConstructors: Fail
-svgelement2_test: Fail
+svg_test/supported_externalResourcesRequired: Fail
+svgelement_test/supported_altGlyph: Fail
+svgelement_test/supported_animate: Fail
+svgelement_test/supported_animateTransform: Fail
+svgelement_test/supported_animateMotion: Fail
+svgelement_test/supported_feBlend: Fail
+svgelement_test/supported_feColorMatrix: Fail
+svgelement_test/supported_feComponentTransfer: Fail
+svgelement_test/supported_feConvolveMatrix: Fail
+svgelement_test/supported_feDiffuseLighting: Fail
+svgelement_test/supported_feDisplacementMap: Fail
+svgelement_test/supported_feDistantLight: Fail
+svgelement_test/supported_feFlood: Fail
+svgelement_test/supported_feFuncA: Fail
+svgelement_test/supported_feFuncB: Fail
+svgelement_test/supported_feFuncG: Fail
+svgelement_test/supported_feFuncR: Fail
+svgelement_test/supported_feGaussianBlur: Fail
+svgelement_test/supported_feImage: Fail
+svgelement_test/supported_feMerge: Fail
+svgelement_test/supported_feMergeNode: Fail
+svgelement_test/supported_feOffset: Fail
+svgelement_test/supported_fePointLight: Fail
+svgelement_test/supported_feSpecularLighting: Fail
+svgelement_test/supported_feSpotLight: Fail
+svgelement_test/supported_feTile: Fail
+svgelement_test/supported_feTurbulence: Fail
+svgelement_test/supported_filter: Fail
+svgelement_test/supported_foreignObject: Fail
+svgelement_test/supported_set: Fail
 touchevent_test/supported: Fail
 url_test: Fail              # IE9 does not support createObjectURL (it is supported in IE10)
 websocket_test/supported: Fail
@@ -227,9 +259,8 @@
 performance_api_test/supported: Fail
 serialized_script_value_test: Fail
 speechrecognition_test/supported: Fail
-svg_3_test: Fail
-svgelement_test/additionalConstructors: Fail
-svgelement2_test: Fail
+svg_test/supported_externalResourcesRequired: Fail
+svg_test/supported_langSpace: Fail
 typed_arrays_arraybuffer_test: Fail
 url_test: Fail
 fileapi_test: Skip # Timeout.
@@ -250,6 +281,7 @@
 element_types_test/supported_details: Fail
 element_types_test/supported_embed: Fail
 element_types_test/supported_keygen: Fail
+element_types_test/supported_object: Fail
 element_types_test/supported_shadow: Fail
 element_types_test/supported_track: Fail
 fileapi_test/supported: Fail
@@ -268,10 +300,8 @@
 notifications_test/supported: Fail
 shadow_dom_test/supported: Fail
 speechrecognition_test/supported: Fail
-# Interfaces not implemented: SVGTests, SVGLangSpace, SVGExternalResourcesRequired, SVGStylable
-svg_3_test: Fail
-svgelement_test/additionalConstructors: Fail
-svgelement2_test: Fail
+svg_test/supported_externalResourcesRequired: Fail
+svg_test/supported_langSpace: Fail
 touchevent_test/supported: Fail
 transferables_test: Fail   # Issue 3392.
 webgl_1_test: Pass, Fail   # Issue 8219
@@ -301,4 +331,3 @@
 
 [ $compiler == dart2js && $runtime == ff ]
 inner_frame_test: Skip # Timeout
-svg_3_test: Skip # Timeout
diff --git a/tests/html/svg_1_test.dart b/tests/html/svg_1_test.dart
deleted file mode 100644
index d5033c4..0000000
--- a/tests/html/svg_1_test.dart
+++ /dev/null
@@ -1,46 +0,0 @@
-library SVG1Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
-import 'dart:html';
-import 'dart:svg' as svg;
-
-// Test that SVG is present in dart:html API
-
-main() {
-  useHtmlConfiguration();
-
-  var isSvgElement = predicate((x) => x is svg.SvgElement, 'is a SvgElement');
-
-  test('simpleRect', () {
-      var div = new Element.tag('div');
-      document.body.nodes.add(div);
-      div.innerHtml = r'''
-<svg id='svg1' width='200' height='100'>
-<rect id='rect1' x='10' y='20' width='130' height='40' rx='5'fill='blue'></rect>
-</svg>
-
-''';
-
-    var e = document.query('#svg1');
-    expect(e, isNotNull);
-
-    svg.RectElement r = document.query('#rect1');
-    expect(r.x.baseVal.value, 10);
-    expect(r.y.baseVal.value, 20);
-    expect(r.height.baseVal.value, 40);
-    expect(r.width.baseVal.value, 130);
-    expect(r.rx.baseVal.value, 5);
-  });
-
-  test('trailing newline', () {
-    // Ensures that we handle SVG with trailing newlines.
-    var logo = new svg.SvgElement.svg("""
-      <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
-        <path/>
-      </svg>
-      """);
-
-  expect(logo, isSvgElement);
-
-  });
-}
diff --git a/tests/html/svg_2_test.dart b/tests/html/svg_2_test.dart
deleted file mode 100644
index b2c4547..0000000
--- a/tests/html/svg_2_test.dart
+++ /dev/null
@@ -1,65 +0,0 @@
-library SVG2Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
-import 'dart:html';
-import 'dart:svg' as svg;
-
-// Test that SVG elements explicitly implement the IDL interfaces (is-checks
-// only, see SVGTest3 for behavioural tests).
-
-main() {
-
-  insertTestDiv() {
-    var element = new Element.tag('div');
-    element.innerHtml = r'''
-<svg id='svg1' width='200' height='100'>
-<rect id='rect1' x='10' y='20' width='130' height='40' rx='5'fill='blue'></rect>
-</svg>
-''';
-    document.body.nodes.add(element);
-    return element;
-  }
-
-  useHtmlConfiguration();
-
-  var isElement = predicate((x) => x is Element, 'is an Element');
-  var isSvgElement = predicate((x) => x is svg.SvgElement, 'is a SvgElement');
-  var isSvgSvgElement =
-      predicate((x) => x is svg.SvgSvgElement, 'is a SvgSvgElement');
-  var isNode = predicate((x) => x is Node, 'is a Node');
-  var isSvgTests = predicate((x) => x is svg.Tests, 'is a svg.Tests');
-  var isSvgLangSpace = predicate((x) => x is svg.LangSpace, 'is a svg.LangSpace');
-  var isSvgExternalResourcesRequired =
-      predicate((x) => x is svg.ExternalResourcesRequired,
-          'is a svg.ExternalResourcesRequired');
-  var isSvgTransformable =
-      predicate((x) => x is svg.Transformable, 'is a svg.Transformable');
-  var isSvgLocatable =
-      predicate((x) => x is svg.Locatable, 'is a svg.Locatable');
-  var isSvgNumber = predicate((x) => x is svg.Number, 'is a svg.Number');
-  var isSvgRect = predicate((x) => x is svg.Rect, 'is a svg.Rect');
-
-  test('rect_isChecks', () {
-      var div = insertTestDiv();
-      var r = document.query('#rect1');
-
-      // Direct inheritance chain
-      expect(r, isSvgElement);
-      expect(r, isElement);
-      expect(r, isNode);
-
-      // Other implemented interfaces.
-      expect(r, isSvgTests);
-      expect(r, isSvgLangSpace);
-      expect(r, isSvgExternalResourcesRequired);
-      expect(r, isSvgTransformable);
-      expect(r, isSvgLocatable);
-
-      // Interfaces not implemented.
-      expect(r, isNot(isSvgNumber));
-      expect(r, isNot(isSvgRect));
-      expect(r, isNot(isSvgSvgElement));
-
-      div.remove();
-    });
-}
diff --git a/tests/html/svg_3_test.dart b/tests/html/svg_3_test.dart
deleted file mode 100644
index 91e2eee..0000000
--- a/tests/html/svg_3_test.dart
+++ /dev/null
@@ -1,129 +0,0 @@
-library SVG3Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
-import 'dart:html';
-import 'dart:svg' as svg;
-
-// Test that SVG elements have the operations advertised through all the IDL
-// interfaces.  This is a 'duck typing' test, and does not explicitly use 'is'
-// checks on the expected interfaces (that is in SVGTest2).
-
-main() {
-
-  var isString = predicate((x) => x is String, 'is a String');
-  var isStringList = predicate((x) => x is List<String>, 'is a List<String>');
-  var isSvgMatrix = predicate((x) => x is svg.Matrix, 'is a svg.Matrix');
-  var isSvgAnimatedBoolean =
-      predicate((x) => x is svg.AnimatedBoolean, 'is an svg.AnimatedBoolean');
-  var isSvgAnimatedString =
-      predicate((x) => x is svg.AnimatedString, 'is an svg.AnimatedString');
-  var isSvgRect = predicate((x) => x is svg.Rect, 'is a svg.Rect');
-  var isSvgAnimatedTransformList =
-      predicate((x) => x is svg.AnimatedTransformList,
-          'is an svg.AnimatedTransformList');
-  var isCssStyleDeclaration =
-      predicate((x) => x is CssStyleDeclaration, 'is a CssStyleDeclaration');
-  var isCssValue = predicate((x) => x is CssValue, 'is a CssValue');
-
-  insertTestDiv() {
-    var element = new Element.tag('div');
-    element.innerHtml = r'''
-<svg id='svg1' width='200' height='100'>
-<rect id='rect1' x='10' y='20' width='130' height='40' rx='5'fill='blue'></rect>
-</svg>
-''';
-    document.body.nodes.add(element);
-    return element;
-  }
-
-  useHtmlConfiguration();
-
-  /**
-   * Verifies that [e] supports the operations on the svg.Tests interface.
-   */
-  checkSvgTests(e) {
-    // Just check that the operations seem to exist.
-    var rx = e.requiredExtensions;
-    expect(rx, isStringList);
-    var rf = e.requiredFeatures;
-    expect(rf, isStringList);
-    var sl = e.systemLanguage;
-    expect(sl, isStringList);
-
-    bool hasDoDo = e.hasExtension("DoDo");
-    expect(hasDoDo, isFalse);
-  }
-
-  /**
-   * Verifies that [e] supports the operations on the svg.LangSpace interface.
-   */
-  checkSvgLangSpace(e) {
-    // Just check that the attribtes seem to exist.
-    var lang = e.xmllang;
-    e.xmllang = lang;
-
-    String space = e.xmlspace;
-    e.xmlspace = space;
-
-    expect(lang, isString);
-    expect(space, isString);
-  }
-
-  /**
-   * Verifies that [e] supports the operations on the
-   * svg.ExternalResourcesRequired interface.
-   */
-  checkSvgExternalResourcesRequired(e) {
-    var b = e.externalResourcesRequired;
-    expect(b, isSvgAnimatedBoolean);
-    expect(b.baseVal, isFalse);
-    expect(b.animVal, isFalse);
-  }
-
-  /**
-   * Verifies that [e] supports the operations on the svg.Locatable interface.
-   */
-  checkSvgLocatable(e) {
-    var v1 = e.farthestViewportElement;
-    var v2 = e.nearestViewportElement;
-    expect(v1, same(v2));
-
-    var bbox = e.getBBox();
-    expect(bbox, isSvgRect);
-
-    var ctm = e.getCtm();
-    expect(ctm, isSvgMatrix);
-
-    var sctm = e.getScreenCtm();
-    expect(sctm, isSvgMatrix);
-
-    var xf2e = e.getTransformToElement(e);
-    expect(xf2e, isSvgMatrix);
-  }
-
-  /**
-   * Verifies that [e] supports the operations on the svg.Transformable
-   * interface.
-   */
-  checkSvgTransformable(e) {
-    var trans = e.transform;
-    expect(trans, isSvgAnimatedTransformList);
-  }
-
-  testRect(name, checker) {
-    test(name, () {
-        var div = insertTestDiv();
-        var r = document.query('#rect1');
-        checker(r);
-        div.remove();
-      });
-  }
-
-  testRect('rect_SvgTests', checkSvgTests);
-  testRect('rect_SvgLangSpace', checkSvgLangSpace);
-  testRect('rect_SvgExternalResourcesRequired',
-           checkSvgExternalResourcesRequired);
-  testRect('rect_SvgLocatable', checkSvgLocatable);
-  testRect('rect_SvgTransformable', checkSvgTransformable);
-
-}
diff --git a/tests/html/svg_test.dart b/tests/html/svg_test.dart
new file mode 100644
index 0000000..0c60712
--- /dev/null
+++ b/tests/html/svg_test.dart
@@ -0,0 +1,247 @@
+// 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.
+
+library SVGTest;
+import '../../pkg/unittest/lib/unittest.dart';
+import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'dart:html';
+import 'dart:svg' as svg;
+
+main() {
+  useHtmlIndividualConfiguration();
+
+  group('svgPresence', () {
+    var isSvgElement = predicate((x) => x is svg.SvgElement, 'is a SvgElement');
+
+    test('simpleRect', () {
+      var div = new Element.tag('div');
+      document.body.nodes.add(div);
+      div.innerHtml = r'''
+<svg id='svg1' width='200' height='100'>
+<rect id='rect1' x='10' y='20' width='130' height='40' rx='5'fill='blue'></rect>
+</svg>
+
+''';
+
+      var e = document.query('#svg1');
+      expect(e, isNotNull);
+
+      svg.RectElement r = document.query('#rect1');
+      expect(r.x.baseVal.value, 10);
+      expect(r.y.baseVal.value, 20);
+      expect(r.height.baseVal.value, 40);
+      expect(r.width.baseVal.value, 130);
+      expect(r.rx.baseVal.value, 5);
+    });
+
+    test('trailing newline', () {
+      // Ensures that we handle SVG with trailing newlines.
+      var logo = new svg.SvgElement.svg("""
+        <svg xmlns='http://www.w3.org/2000/svg' version='1.1'>
+          <path/>
+        </svg>
+        """);
+
+    expect(logo, isSvgElement);
+
+    });
+  });
+
+  group('svgInterfaceMatch', () {
+    // Test that SVG elements explicitly implement the IDL interfaces (is-checks
+    // only, see SVGTest3 for behavioural tests).
+    insertTestDiv() {
+      var element = new Element.tag('div');
+      element.innerHtml = r'''
+<svg id='svg1' width='200' height='100'>
+<rect id='rect1' x='10' y='20' width='130' height='40' rx='5'fill='blue'></rect>
+</svg>
+''';
+      document.body.nodes.add(element);
+      return element;
+    }
+
+
+    var isElement = predicate((x) => x is Element, 'is an Element');
+    var isSvgElement = predicate((x) => x is svg.SvgElement, 'is a SvgElement');
+    var isSvgSvgElement =
+        predicate((x) => x is svg.SvgSvgElement, 'is a SvgSvgElement');
+    var isNode = predicate((x) => x is Node, 'is a Node');
+    var isSvgTests = predicate((x) => x is svg.Tests, 'is a svg.Tests');
+    var isSvgLangSpace = predicate((x) => x is svg.LangSpace, 'is a svg.LangSpace');
+    var isSvgExternalResourcesRequired =
+        predicate((x) => x is svg.ExternalResourcesRequired,
+            'is a svg.ExternalResourcesRequired');
+    var isSvgTransformable =
+        predicate((x) => x is svg.Transformable, 'is a svg.Transformable');
+    var isSvgLocatable =
+        predicate((x) => x is svg.Locatable, 'is a svg.Locatable');
+    var isSvgNumber = predicate((x) => x is svg.Number, 'is a svg.Number');
+    var isSvgRect = predicate((x) => x is svg.Rect, 'is a svg.Rect');
+
+    test('rect_isChecks', () {
+        var div = insertTestDiv();
+        var r = document.query('#rect1');
+
+        // Direct inheritance chain
+        expect(r, isSvgElement);
+        expect(r, isElement);
+        expect(r, isNode);
+
+        // Other implemented interfaces.
+        expect(r, isSvgTests);
+        expect(r, isSvgLangSpace);
+        expect(r, isSvgExternalResourcesRequired);
+        expect(r, isSvgTransformable);
+        expect(r, isSvgLocatable);
+
+        // Interfaces not implemented.
+        expect(r, isNot(isSvgNumber));
+        expect(r, isNot(isSvgRect));
+        expect(r, isNot(isSvgSvgElement));
+
+        div.remove();
+      });
+    });
+
+  insertTestDiv() {
+    var element = new Element.tag('div');
+    element.innerHtml = r'''
+<svg id='svg1' width='200' height='100'>
+<rect id='rect1' x='10' y='20' width='130' height='40' rx='5'fill='blue'></rect>
+</svg>
+''';
+    document.body.nodes.add(element);
+    return element;
+  }
+
+  group('supported_externalResourcesRequired', () {
+    test('supported', () {
+      var div = insertTestDiv();
+      var r = document.query('#rect1');
+      expect(svg.ExternalResourcesRequired.supported(r), true);
+      div.remove();
+    });
+  });
+
+  group('supported_langSpace', () {
+    test('supported', () {
+      var div = insertTestDiv();
+      var r = document.query('#rect1');
+      expect(svg.LangSpace.supported(r), true);
+      div.remove();
+    });
+  });
+
+  group('svgBehavioral', () {
+
+    // Test that SVG elements have the operations advertised through all the IDL
+    // interfaces.  This is a 'duck typing' test, and does not explicitly use
+    // 'is' checks on the expected interfaces (that is in the test group above).
+
+    var isString = predicate((x) => x is String, 'is a String');
+    var isStringList = predicate((x) => x is List<String>, 'is a List<String>');
+    var isSvgMatrix = predicate((x) => x is svg.Matrix, 'is a svg.Matrix');
+    var isSvgAnimatedBoolean =
+        predicate((x) => x is svg.AnimatedBoolean, 'is an svg.AnimatedBoolean');
+    var isSvgAnimatedString =
+        predicate((x) => x is svg.AnimatedString, 'is an svg.AnimatedString');
+    var isSvgRect = predicate((x) => x is svg.Rect, 'is a svg.Rect');
+    var isSvgAnimatedTransformList =
+        predicate((x) => x is svg.AnimatedTransformList,
+            'is an svg.AnimatedTransformList');
+    var isCssStyleDeclaration =
+        predicate((x) => x is CssStyleDeclaration, 'is a CssStyleDeclaration');
+    var isCssValue = predicate((x) => x is CssValue, 'is a CssValue');
+
+    /// Verifies that [e] supports the operations on the svg.Tests interface.
+    checkSvgTests(e) {
+      // Just check that the operations seem to exist.
+      var rx = e.requiredExtensions;
+      expect(rx, isStringList);
+      var rf = e.requiredFeatures;
+      expect(rf, isStringList);
+      var sl = e.systemLanguage;
+      expect(sl, isStringList);
+
+      bool hasDoDo = e.hasExtension("DoDo");
+      expect(hasDoDo, isFalse);
+    }
+
+    /// Verifies that [e] supports the operations on the svg.Locatable interface.
+    checkSvgLocatable(e) {
+      var v1 = e.farthestViewportElement;
+      var v2 = e.nearestViewportElement;
+      expect(v1, same(v2));
+
+      var bbox = e.getBBox();
+      expect(bbox, isSvgRect);
+
+      var ctm = e.getCtm();
+      expect(ctm, isSvgMatrix);
+
+      var sctm = e.getScreenCtm();
+      expect(sctm, isSvgMatrix);
+
+      var xf2e = e.getTransformToElement(e);
+      expect(xf2e, isSvgMatrix);
+    }
+
+    /**
+     * Verifies that [e] supports the operations on the svg.Transformable
+     * interface.
+     */
+    checkSvgTransformable(e) {
+      var trans = e.transform;
+      expect(trans, isSvgAnimatedTransformList);
+    }
+
+    testRect(name, checker) {
+      test(name, () {
+        var div = insertTestDiv();
+        var r = document.query('#rect1');
+        checker(r);
+        div.remove();
+      });
+    }
+
+    /**
+     * Verifies that [e] supports the operations on the svg.LangSpace interface.
+     */
+    checkSvgLangSpace(e) {
+      if (svg.LangSpace.supported(e)) {
+        // Just check that the attributes seem to exist.
+        var lang = e.xmllang;
+        e.xmllang = lang;
+
+        String space = e.xmlspace;
+        e.xmlspace = space;
+
+        expect(lang, isString);
+        expect(space, isString);
+      }
+    }
+
+    /**
+     * Verifies that [e] supports the operations on the
+     * svg.ExternalResourcesRequired interface.
+     */
+    checkSvgExternalResourcesRequired(e) {
+      if (svg.ExternalResourcesRequired.supported(e)) {
+        var b = e.externalResourcesRequired;
+        expect(b, isSvgAnimatedBoolean);
+        expect(b.baseVal, isFalse);
+        expect(b.animVal, isFalse);
+      }
+    }
+
+    testRect('rect_SvgTests', checkSvgTests);
+    testRect('rect_SvgLangSpace', checkSvgLangSpace);
+    testRect('rect_SvgExternalResourcesRequired',
+             checkSvgExternalResourcesRequired);
+    testRect('rect_SvgLocatable', checkSvgLocatable);
+    testRect('rect_SvgTransformable', checkSvgTransformable);
+  });
+
+}
diff --git a/tests/html/svgelement2_test.dart b/tests/html/svgelement2_test.dart
deleted file mode 100644
index 468b61a..0000000
--- a/tests/html/svgelement2_test.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2011, 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.
-
-library SVGElement2Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
-import 'svgelement_test.dart' as originalTest;
-
-class A {
-  var _this;
-  A(x) : this._this = x;
-}
-
-main() {
-  // The svgelement_test requires the field "_this" to map to "_this". In this
-  // test-case we use another library's '_this' first (see issue 3039 and
-  // _ChildNodeListLazy.first).
-  expect(new A(499)._this, 499);
-  originalTest.main();
-}
diff --git a/tests/html/svgelement_test.dart b/tests/html/svgelement_test.dart
index 333bca8..52787a2 100644
--- a/tests/html/svgelement_test.dart
+++ b/tests/html/svgelement_test.dart
@@ -27,126 +27,316 @@
     return out;
   };
 
-  testConstructor(String tagName, Function isExpectedClass) {
+  testConstructor(String tagName, Function isExpectedClass,
+      [bool expectation = true]) {
     test(tagName, () {
-      expect(isExpectedClass(new svg.SvgElement.tag(tagName)), isTrue);
+      expect(isExpectedClass(new svg.SvgElement.tag(tagName)), expectation);
       expect(isExpectedClass(
-          new svg.SvgElement.svg('<$tagName></$tagName>')), isTrue);
+          new svg.SvgElement.svg('<$tagName></$tagName>')), expectation);
     });
   }
   group('additionalConstructors', () {
-    group('svg', () {
-      test('valid', () {
-        final svgContent = """
+    test('valid', () {
+      final svgContent = """
 <svg version="1.1">
   <circle></circle>
   <path></path>
 </svg>""";
-        final el = new svg.SvgElement.svg(svgContent);
-        expect(el, isSvgSvgElement);
-        expect(el.innerHtml, "<circle></circle><path></path>");
-        expect(el.outerHtml, svgContent);
-      });
-
-      test('has no parent', () =>
-        expect(new svg.SvgElement.svg('<circle/>').parent, isNull)
-      );
-
-      test('empty', () {
-        expect(() => new svg.SvgElement.svg(""), throwsArgumentError);
-      });
-
-      test('too many elements', () {
-        expect(() => new svg.SvgElement.svg("<circle></circle><path></path>"),
-            throwsArgumentError);
-      });
+      final el = new svg.SvgElement.svg(svgContent);
+      expect(el, isSvgSvgElement);
+      expect(el.innerHtml, anyOf("<circle></circle><path></path>", '<circle '
+          'xmlns="http://www.w3.org/2000/svg" /><path '
+          'xmlns="http://www.w3.org/2000/svg" />'));
+      expect(el.outerHtml, anyOf(svgContent,
+          '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">\n  '
+          '<circle />\n  <path />\n</svg>'));
     });
-    testConstructor('altGlyphDef', (e) => e is svg.AltGlyphDefElement);
-    testConstructor('altGlyph', (e) => e is svg.AltGlyphElement);
-    testConstructor('animateColor', (e) => e is svg.AnimateColorElement);
-    testConstructor('animate', (e) => e is svg.AnimateElement);
-    // WebKit doesn't recognize animateMotion
-    // testConstructor('animateMotion', (e) => e is svg.AnimateMotionElement);
-    testConstructor('animateTransform', (e) => e is svg.AnimateTransformElement);
-    testConstructor('cursor', (e) => e is svg.CursorElement);
-    testConstructor('feBlend', (e) => e is svg.FEBlendElement);
-    testConstructor('feColorMatrix', (e) => e is svg.FEColorMatrixElement);
-    testConstructor('feComponentTransfer',
-        (e) => e is svg.FEComponentTransferElement);
-    testConstructor('feConvolveMatrix', (e) => e is svg.FEConvolveMatrixElement);
-    testConstructor('feDiffuseLighting',
-        (e) => e is svg.FEDiffuseLightingElement);
-    testConstructor('feDisplacementMap',
-        (e) => e is svg.FEDisplacementMapElement);
-    testConstructor('feDistantLight', (e) => e is svg.FEDistantLightElement);
-    testConstructor('feDropShadow', (e) => e is svg.FEDropShadowElement);
-    testConstructor('feFlood', (e) => e is svg.FEFloodElement);
-    testConstructor('feFuncA', (e) => e is svg.FEFuncAElement);
-    testConstructor('feFuncB', (e) => e is svg.FEFuncBElement);
-    testConstructor('feFuncG', (e) => e is svg.FEFuncGElement);
-    testConstructor('feFuncR', (e) => e is svg.FEFuncRElement);
-    testConstructor('feGaussianBlur', (e) => e is svg.FEGaussianBlurElement);
-    testConstructor('feImage', (e) => e is svg.FEImageElement);
-    testConstructor('feMerge', (e) => e is svg.FEMergeElement);
-    testConstructor('feMergeNode', (e) => e is svg.FEMergeNodeElement);
-    testConstructor('feOffset', (e) => e is svg.FEOffsetElement);
-    testConstructor('fePointLight', (e) => e is svg.FEPointLightElement);
-    testConstructor('feSpecularLighting',
-        (e) => e is svg.FESpecularLightingElement);
-    testConstructor('feSpotLight', (e) => e is svg.FESpotLightElement);
-    testConstructor('feTile', (e) => e is svg.FETileElement);
-    testConstructor('feTurbulence', (e) => e is svg.FETurbulenceElement);
-    testConstructor('filter', (e) => e is svg.FilterElement);
-    testConstructor('font', (e) => e is svg.FontElement);
-    testConstructor('font-face', (e) => e is svg.FontFaceElement);
-    testConstructor('font-face-format', (e) => e is svg.FontFaceFormatElement);
-    testConstructor('font-face-name', (e) => e is svg.FontFaceNameElement);
-    testConstructor('font-face-src', (e) => e is svg.FontFaceSrcElement);
-    testConstructor('font-face-uri', (e) => e is svg.FontFaceUriElement);
-    testConstructor('foreignObject', (e) => e is svg.ForeignObjectElement);
-    testConstructor('glyph', (e) => e is svg.GlyphElement);
-    testConstructor('glyphRef', (e) => e is svg.GlyphRefElement);
-    testConstructor('metadata', (e) => e is svg.MetadataElement);
-    testConstructor('missing-glyph', (e) => e is svg.MissingGlyphElement);
-    testConstructor('set', (e) => e is svg.SetElement);
-    testConstructor('tref', (e) => e is svg.TRefElement);
-    testConstructor('vkern', (e) => e is svg.VKernElement);
+
+    test('has no parent', () =>
+      expect(new svg.SvgElement.svg('<circle/>').parent, isNull)
+    );
+
+    test('empty', () {
+      expect(() => new svg.SvgElement.svg(""), throwsArgumentError);
+    });
+
+    test('too many elements', () {
+      expect(() => new svg.SvgElement.svg("<circle></circle><path></path>"),
+          throwsArgumentError);
+    });
+  });
+
+  // Unfortunately, because the filtering mechanism in unitttest is a regex done
+  group('supported_altGlyph', () {
+    test('supported', () {
+      expect(svg.AltGlyphElement.supported, true);
+    });
+  });
+
+  group('supported_animate', () {
+    test('supported', () {
+      expect(svg.AnimateElement.supported, true);
+    });
+  });
+
+  group('supported_animateMotion', () {
+    test('supported', () {
+      expect(svg.AnimateMotionElement.supported, true);
+    });
+  });
+
+  group('supported_animateTransform', () {
+    test('supported', () {
+      expect(svg.AnimateTransformElement.supported, true);
+    });
+  });
+
+  group('supported_feBlend', () {
+    test('supported', () {
+      expect(svg.FEBlendElement.supported, true);
+    });
+  });
+
+  group('supported_feColorMatrix', () {
+    test('supported', () {
+      expect(svg.FEColorMatrixElement.supported, true);
+    });
+  });
+
+  group('supported_feComponentTransfer', () {
+    test('supported', () {
+      expect(svg.FEComponentTransferElement.supported, true);
+    });
+  });
+
+  group('supported_feConvolveMatrix', () {
+    test('supported', () {
+      expect(svg.FEConvolveMatrixElement.supported, true);
+    });
+  });
+
+  group('supported_feDiffuseLighting', () {
+    test('supported', () {
+      expect(svg.FEDiffuseLightingElement.supported, true);
+    });
+  });
+
+  group('supported_feDisplacementMap', () {
+    test('supported', () {
+      expect(svg.FEDisplacementMapElement.supported, true);
+    });
+  });
+
+  group('supported_feDistantLight', () {
+    test('supported', () {
+      expect(svg.FEDistantLightElement.supported, true);
+    });
+  });
+
+  group('supported_feFlood', () {
+    test('supported', () {
+      expect(svg.FEFloodElement.supported, true);
+    });
+  });
+
+  group('supported_feFuncA', () {
+    test('supported', () {
+      expect(svg.FEFuncAElement.supported, true);
+    });
+  });
+
+  group('supported_feFuncB', () {
+    test('supported', () {
+      expect(svg.FEFuncBElement.supported, true);
+    });
+  });
+
+  group('supported_feFuncG', () {
+    test('supported', () {
+      expect(svg.FEFuncGElement.supported, true);
+    });
+  });
+
+  group('supported_feFuncR', () {
+    test('supported', () {
+      expect(svg.FEFuncRElement.supported, true);
+    });
+  });
+
+  group('supported_feGaussianBlur', () {
+    test('supported', () {
+      expect(svg.FEGaussianBlurElement.supported, true);
+    });
+  });
+
+  group('supported_feImage', () {
+    test('supported', () {
+      expect(svg.FEImageElement.supported, true);
+    });
+  });
+
+  group('supported_feMerge', () {
+    test('supported', () {
+      expect(svg.FEMergeElement.supported, true);
+    });
+  });
+
+  group('supported_feMergeNode', () {
+    test('supported', () {
+      expect(svg.FEMergeNodeElement.supported, true);
+    });
+  });
+
+  group('supported_feOffset', () {
+    test('supported', () {
+      expect(svg.FEOffsetElement.supported, true);
+    });
+  });
+
+  group('supported_feComponentTransfer', () {
+    test('supported', () {
+      expect(svg.FEPointLightElement.supported, true);
+    });
+  });
+
+  group('supported_feSpecularLighting', () {
+    test('supported', () {
+      expect(svg.FESpecularLightingElement.supported, true);
+    });
+  });
+
+  group('supported_feComponentTransfer', () {
+    test('supported', () {
+      expect(svg.FESpotLightElement.supported, true);
+    });
+  });
+
+  group('supported_feTile', () {
+    test('supported', () {
+      expect(svg.FETileElement.supported, true);
+    });
+  });
+
+  group('supported_feTurbulence', () {
+    test('supported', () {
+      expect(svg.FETurbulenceElement.supported, true);
+    });
+  });
+
+  group('supported_filter', () {
+    test('supported', () {
+      expect(svg.FilterElement.supported, true);
+    });
+  });
+
+  group('supported_foreignObject', () {
+    test('supported', () {
+      expect(svg.ForeignObjectElement.supported, true);
+    });
+  });
+
+  group('supported_set', () {
+    test('supported', () {
+      expect(svg.SetElement.supported, true);
+    });
   });
 
   group('constructors', () {
-    testConstructor('a', (e) => e is svg.AElement);
-    testConstructor('circle', (e) => e is svg.CircleElement);
-    testConstructor('clipPath', (e) => e is svg.ClipPathElement);
-    testConstructor('defs', (e) => e is svg.DefsElement);
-    testConstructor('desc', (e) => e is svg.DescElement);
-    testConstructor('ellipse', (e) => e is svg.EllipseElement);
-    testConstructor('g', (e) => e is svg.GElement);
-    // WebKit doesn't recognize hkern
-    // testConstructor('hkern', (e) => e is svg.HKernElement);
-    testConstructor('image', (e) => e is svg.ImageElement);
-    testConstructor('line', (e) => e is svg.LineElement);
-    testConstructor('linearGradient', (e) => e is svg.LinearGradientElement);
-    // WebKit doesn't recognize mpath
-    // testConstructor('mpath', (e) => e is svg.MPathElement);
-    testConstructor('marker', (e) => e is svg.MarkerElement);
-    testConstructor('mask', (e) => e is svg.MaskElement);
-    testConstructor('path', (e) => e is svg.PathElement);
-    testConstructor('pattern', (e) => e is svg.PatternElement);
-    testConstructor('polygon', (e) => e is svg.PolygonElement);
-    testConstructor('polyline', (e) => e is svg.PolylineElement);
-    testConstructor('radialGradient', (e) => e is svg.RadialGradientElement);
-    testConstructor('rect', (e) => e is svg.RectElement);
-    testConstructor('script', (e) => e is svg.ScriptElement);
-    testConstructor('stop', (e) => e is svg.StopElement);
-    testConstructor('style', (e) => e is svg.StyleElement);
-    testConstructor('switch', (e) => e is svg.SwitchElement);
-    testConstructor('symbol', (e) => e is svg.SymbolElement);
-    testConstructor('tspan', (e) => e is svg.TSpanElement);
-    testConstructor('text', (e) => e is svg.TextElement);
-    testConstructor('textPath', (e) => e is svg.TextPathElement);
-    testConstructor('title', (e) => e is svg.TitleElement);
-    testConstructor('use', (e) => e is svg.UseElement);
-    testConstructor('view', (e) => e is svg.ViewElement);
+    test('supported', () {
+      testConstructor('a', (e) => e is svg.AElement);
+      testConstructor('circle', (e) => e is svg.CircleElement);
+      testConstructor('clipPath', (e) => e is svg.ClipPathElement);
+      testConstructor('defs', (e) => e is svg.DefsElement);
+      testConstructor('desc', (e) => e is svg.DescElement);
+      testConstructor('ellipse', (e) => e is svg.EllipseElement);
+      testConstructor('g', (e) => e is svg.GElement);
+      testConstructor('image', (e) => e is svg.ImageElement);
+      testConstructor('line', (e) => e is svg.LineElement);
+      testConstructor('linearGradient', (e) => e is svg.LinearGradientElement);
+      testConstructor('marker', (e) => e is svg.MarkerElement);
+      testConstructor('mask', (e) => e is svg.MaskElement);
+      testConstructor('path', (e) => e is svg.PathElement);
+      testConstructor('pattern', (e) => e is svg.PatternElement);
+      testConstructor('polygon', (e) => e is svg.PolygonElement);
+      testConstructor('polyline', (e) => e is svg.PolylineElement);
+      testConstructor('radialGradient', (e) => e is svg.RadialGradientElement);
+      testConstructor('rect', (e) => e is svg.RectElement);
+      testConstructor('script', (e) => e is svg.ScriptElement);
+      testConstructor('stop', (e) => e is svg.StopElement);
+      testConstructor('style', (e) => e is svg.StyleElement);
+      testConstructor('switch', (e) => e is svg.SwitchElement);
+      testConstructor('symbol', (e) => e is svg.SymbolElement);
+      testConstructor('tspan', (e) => e is svg.TSpanElement);
+      testConstructor('text', (e) => e is svg.TextElement);
+      testConstructor('textPath', (e) => e is svg.TextPathElement);
+      testConstructor('title', (e) => e is svg.TitleElement);
+      testConstructor('use', (e) => e is svg.UseElement);
+      testConstructor('view', (e) => e is svg.ViewElement);
+      testConstructor('altGlyph', (e) => e is svg.AltGlyphElement,
+          svg.AltGlyphElement.supported);
+      testConstructor('animate', (e) => e is svg.AnimateElement,
+          svg.AnimateElement.supported);
+      testConstructor('animateMotion', (e) => e is svg.AnimateMotionElement,
+          svg.AnimateMotionElement.supported);
+      testConstructor('animateTransform', (e) => e is svg.AnimateTransformElement,
+          svg.AnimateTransformElement.supported);
+      testConstructor('feBlend', (e) => e is svg.FEBlendElement,
+          svg.FEBlendElement.supported);
+      testConstructor('feColorMatrix', (e) => e is svg.FEColorMatrixElement,
+          svg.FEColorMatrixElement.supported);
+      testConstructor('feComponentTransfer',
+          (e) => e is svg.FEComponentTransferElement,
+          svg.FEComponentTransferElement.supported);
+      testConstructor('feConvolveMatrix',
+          (e) => e is svg.FEConvolveMatrixElement,
+          svg.FEConvolveMatrixElement.supported);
+      testConstructor('feDiffuseLighting',
+          (e) => e is svg.FEDiffuseLightingElement,
+          svg.FEDiffuseLightingElement.supported);
+      testConstructor('feDisplacementMap',
+          (e) => e is svg.FEDisplacementMapElement,
+          svg.FEDisplacementMapElement.supported);
+      testConstructor('feDistantLight', (e) => e is svg.FEDistantLightElement,
+          svg.FEDistantLightElement.supported);
+      testConstructor('feFlood', (e) => e is svg.FEFloodElement,
+          svg.FEFloodElement.supported);
+      testConstructor('feFuncA', (e) => e is svg.FEFuncAElement,
+          svg.FEFuncAElement.supported);
+      testConstructor('feFuncB', (e) => e is svg.FEFuncBElement,
+          svg.FEFuncBElement.supported);
+      testConstructor('feFuncG', (e) => e is svg.FEFuncGElement,
+          svg.FEFuncGElement.supported);
+      testConstructor('feFuncR', (e) => e is svg.FEFuncRElement,
+          svg.FEFuncRElement.supported);
+      testConstructor('feGaussianBlur', (e) => e is svg.FEGaussianBlurElement,
+          svg.FEGaussianBlurElement.supported);
+      testConstructor('feImage', (e) => e is svg.FEImageElement,
+          svg.FEImageElement.supported);
+      testConstructor('feMerge', (e) => e is svg.FEMergeElement,
+          svg.FEMergeElement.supported);
+      testConstructor('feMergeNode', (e) => e is svg.FEMergeNodeElement,
+          svg.FEMergeNodeElement.supported);
+      testConstructor('feOffset', (e) => e is svg.FEOffsetElement,
+          svg.FEOffsetElement.supported);
+      testConstructor('fePointLight', (e) => e is svg.FEPointLightElement,
+          svg.FEPointLightElement.supported);
+      testConstructor('feSpecularLighting',
+          (e) => e is svg.FESpecularLightingElement,
+          svg.FESpecularLightingElement.supported);
+      testConstructor('feSpotLight', (e) => e is svg.FESpotLightElement,
+          svg.FESpotLightElement.supported);
+      testConstructor('feTile', (e) => e is svg.FETileElement,
+          svg.FETileElement.supported);
+      testConstructor('feTurbulence', (e) => e is svg.FETurbulenceElement,
+          svg.FETurbulenceElement.supported);
+      testConstructor('filter', (e) => e is svg.FilterElement,
+          svg.FilterElement.supported);
+      testConstructor('foreignObject', (e) => e is svg.ForeignObjectElement,
+          svg.ForeignObjectElement.supported);
+      testConstructor('metadata', (e) => e is svg.MetadataElement);
+      testConstructor('set', (e) => e is svg.SetElement,
+          svg.SetElement.supported);
+    });
   });
 
   group('outerHtml', () {
diff --git a/tests/language/div_with_power_of_two_test.dart b/tests/language/div_with_power_of_two_test.dart
new file mode 100644
index 0000000..fbd3151
--- /dev/null
+++ b/tests/language/div_with_power_of_two_test.dart
@@ -0,0 +1,103 @@
+// 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 division by power of two.
+// Test that results before and after optimization are the same.
+
+// [function, [list of tuples argument/result]].
+var expectedResults =
+  [ [divBy1,
+      [[134217730, 134217730],
+       [-134217730, -134217730],
+       [10, 10],
+       [-10, -10]]],
+    [divByNeg1,
+      [[134217730, -134217730],
+       [-134217730, 134217730],
+       [10, -10],
+       [-10, 10]]],
+    [divBy2,
+      [[134217730, 67108865],
+       [-134217730, -67108865],
+       [10, 5],
+       [-10, -5]]],
+    [divByNeg2,
+      [[134217730, -67108865],
+       [-134217730, 67108865],
+       [10, -5],
+       [-10, 5]]],
+    [divBy4,
+      [[134217730, 33554432],
+       [-134217730, -33554432],
+       [10, 2],
+       [-10, -2]]],
+    [divByNeg4,
+      [[134217730, -33554432],
+       [-134217730, 33554432],
+       [10, -2],
+       [-10, 2]]],
+    [divBy134217728,
+      [[134217730, 1],
+       [-134217730, -1],
+       [10, 0],
+       [-10, 0]]],
+    [divByNeg134217728,
+      [[134217730, -1],
+       [-134217730, 1],
+       [10, 0],
+       [-10, 0]]],
+    // Use different functions for 64 bit arguments.
+    [divBy4_,
+      [[549755813990, 137438953497],
+       [-549755813990, -137438953497],
+       [288230925907525632, 72057731476881408],
+       [-288230925907525632, -72057731476881408]]],
+    [divByNeg4_,
+      [[549755813990, -137438953497],
+       [-549755813990, 137438953497],
+       [288230925907525632, -72057731476881408],
+       [-288230925907525632, 72057731476881408]]],
+    [divBy549755813888,
+      [[549755813990, 1],
+       [-549755813990, -1],
+       [288230925907525632, 524289],
+       [-288230925907525632, -524289]]],
+    [divByNeg549755813888,
+      [[549755813990, -1],
+       [-549755813990, 1],
+       [288230925907525632, -524289],
+       [-288230925907525632, 524289]]],
+  ];
+
+divBy0(a) => a ~/ 0;
+divBy1(a) => a ~/ 1;
+divByNeg1(a) => a ~/ -1;
+divBy2(a) => a ~/ 2;
+divByNeg2(a) => a ~/ -2;
+divBy4(a) => a ~/ 4;
+divByNeg4(a) => a ~/ -4;
+divBy134217728(a) => a ~/ 134217728;
+divByNeg134217728(a) => a ~/ -134217728;
+
+divBy4_(a) => a ~/ 4;
+divByNeg4_(a) => a ~/ -4;
+divBy549755813888(a) => a ~/ 549755813888;
+divByNeg549755813888(a) => a ~/ -549755813888;
+
+main() {
+  for (int i = 0; i < 8000; i++) {
+    for (var e in expectedResults) {
+      Function f = e[0];
+      List values = e[1];
+      for (var v in values) {
+        int arg = v[0];
+        int res = v[1];
+        Expect.equals(res, f(arg));
+      }
+    }
+    try {
+      divBy0(4);
+      Expect.fail("Should have thrown exception.");
+    } on IntegerDivisionByZeroException catch (e) {}
+  }
+}
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 6551691..b50604a 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -90,6 +90,7 @@
 compile_time_constant_checked3_test/06: Fail, OK
 
 [ $compiler == dart2js ]
+div_with_power_of_two_test: Fail # Issue 8301.
 call_operator_test: Fail # Issue 7622.
 class_literal_test: Fail # Issue 7626.
 identical_closure2_test: Fail # Issues 563, 1533
diff --git a/tests/utils/png_layout_test.dart b/tests/utils/png_layout_test.dart
index fe47cb6..13a30f7 100644
--- a/tests/utils/png_layout_test.dart
+++ b/tests/utils/png_layout_test.dart
@@ -17,8 +17,8 @@
   var div2Style = _style('red', 25, 30, 40, 10);
   var div1 = new Element.html('<div style="$div1Style"></div>');
   var div2 = new Element.html('<div style="$div2Style"></div>');
-  document.body.elements.add(div1);
-  document.body.elements.add(div2);
+  document.body.children.add(div1);
+  document.body.children.add(div2);
 }
 
 _style(String color, int top, int left, int width, int height) {
diff --git a/tests/utils/txt_layout_test.dart b/tests/utils/txt_layout_test.dart
index 9573117..6ec9d90 100644
--- a/tests/utils/txt_layout_test.dart
+++ b/tests/utils/txt_layout_test.dart
@@ -17,8 +17,8 @@
   var div2Style = _style('red', 25, 30, 40, 10);
   var div1 = new Element.html('<div style="$div1Style"></div>');
   var div2 = new Element.html('<div style="$div2Style"></div>');
-  document.body.elements.add(div1);
-  document.body.elements.add(div2);
+  document.body.children.add(div1);
+  document.body.children.add(div2);
 }
 
 _style(String color, int top, int left, int width, int height) {
diff --git a/tools/VERSION b/tools/VERSION
index 0445e6e..6e24da0 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
 MINOR 3
-BUILD 3
+BUILD 4
 PATCH 0
diff --git a/tools/create_sdk.py b/tools/create_sdk.py
index 053f110..28882b9 100755
--- a/tools/create_sdk.py
+++ b/tools/create_sdk.py
@@ -268,23 +268,6 @@
        "7zip/7za.exe"),
     ])
 
-  # Copy in cURL on all operating systems, since we need the certificates file
-  # even outside Windows. Leave out the EXE on non-Windows systems, though.
-  curl_ignore_patterns = ignore_patterns('.svn') if HOST_OS == 'win32' \
-      else ignore_patterns('.svn', '*.exe')
-  copytree(join(HOME, 'third_party', 'curl'),
-           join(join(UTIL, 'pub'), 'curl'),
-           ignore=curl_ignore_patterns)
-
-  ReplaceInFiles([
-      join(UTIL, 'pub', 'curl_client.dart'),
-    ], [
-      ("../../third_party/curl/curl.exe",
-       "curl/curl.exe"),
-      ("../../third_party/curl/ca-certificates.crt",
-       "curl/ca-certificates.crt"),
-    ])
-
   version = utils.GetVersion()
 
   # Copy dart2js/dartdoc/pub.
diff --git a/tools/dom/docs/docs.json b/tools/dom/docs/docs.json
index 89087ea..dc6bf6c 100644
--- a/tools/dom/docs/docs.json
+++ b/tools/dom/docs/docs.json
@@ -159,6 +159,20 @@
         ]
       }
     },
+    "HTMLAreaElement": {
+      "comment": [
+        "/**",
+        " * DOM Area Element, which links regions of an image map with a hyperlink.",
+        " *",
+        " * The element can also define an uninteractive region of the map.",
+        " *",
+        " * See also:",
+        " *",
+        " * * [<area>](https://developer.mozilla.org/en-US/docs/HTML/Element/area)",
+        " * on MDN.",
+        " */"
+      ]
+    },
     "HTMLCanvasElement": {
       "members": {
         "height": [
@@ -236,6 +250,58 @@
         " */"
       ]
     },
+    "HTMLMenuElement": {
+      "comment": [
+        "/**",
+        " * An HTML <menu> element.",
+        " *",
+        " * A <menu> element represents an unordered list of menu commands.",
+        " *",
+        " * See also:",
+        " *",
+        " *  * [Menu Element](https://developer.mozilla.org/en-US/docs/HTML/Element/menu) from MDN.",
+        " *  * [Menu Element](http://www.w3.org/TR/html5/the-menu-element.html#the-menu-element) from the W3C.",
+        " */"
+      ]
+    },
+    "WebSocket": {
+      "comment": [
+        "/**",
+        " * Use the WebSocket interface to connect to a WebSocket,",
+        " * and to send and receive data on that WebSocket.",
+        " *",
+        " * To use a WebSocket in your web app, first create a WebSocket object,",
+        " * passing the WebSocket URL as an argument to the constructor.",
+        " *",
+        " *     var webSocket = new WebSocket('ws://127.0.0.1:1337/ws');",
+        " *",
+        " * To send data on the WebSocket, use the [send] method.",
+        " *",
+        " *     if (webSocket != null && webSocket.readyState == WebSocket.OPEN) {",
+        " *       webSocket.send(data);",
+        " *     } else {",
+        " *       print('WebSocket not connected, message $data not sent');",
+        " *     }",
+        " *",
+        " * To receive data on the WebSocket, register a listener for message events.",
+        " *",
+        " *     webSocket.on.message.add((MessageEvent e) {",
+        " *       receivedData(e.data);",
+        " *     });",
+        " *",
+        " * The message event handler receives a [MessageEvent] object",
+        " * as its sole argument.",
+        " * You can also define open, close, and error handlers,",
+        " * as specified by [WebSocketEvents].",
+        " *",
+        " * For more information, see the",
+        " * [WebSockets](http://www.dartlang.org/docs/library-tour/#html-websockets)",
+        " * section of the library tour and",
+        " * [Introducing WebSockets](http://www.html5rocks.com/en/tutorials/websockets/basics/),",
+        " * an HTML5Rocks.com tutorial.",
+        " */"
+      ]
+    },
     "XMLHttpRequest": {
       "members": {
         "abort": [
@@ -267,6 +333,51 @@
           "   * for a list of common response headers.",
           "   */"
         ],
+        "onabort": [
+          "/**",
+          "   * Event listeners to be notified when request has been aborted,",
+          "   * generally due to calling `httpRequest.abort()`.",
+          "   */"
+        ],
+        "onerror": [
+          "/**",
+          "   * Event listeners to be notified when a request has failed, such as when a",
+          "   * cross-domain error occurred or the file wasn't found on the server.",
+          "   */"
+        ],
+        "onload": [
+          "/**",
+          "   * Event listeners to be notified once the request has completed",
+          "   * *successfully*.",
+          "   */"
+        ],
+        "onloadend": [
+          "/**",
+          "   * Event listeners to be notified once the request has completed (on",
+          "   * either success or failure).",
+          "   */"
+        ],
+        "onloadstart": [
+          "/**",
+          "   * Event listeners to be notified when the request starts, once",
+          "   * `httpRequest.send()` has been called.",
+          "   */"
+        ],
+        "onprogress": [
+          "/**",
+          "   * Event listeners to be notified when data for the request",
+          "   * is being sent or loaded.",
+          "   *",
+          "   * Progress events are fired every 50ms or for every byte transmitted,",
+          "   * whichever is less frequent.",
+          "   */"
+        ],
+        "onreadystatechange": [
+          "/**",
+          "   * Event listeners to be notified every time the [HttpRequest]",
+          "   * object's `readyState` changes values.",
+          "   */"
+        ],
         "open": [
           "/**",
           "   * Specify the desired `url`, and `method` to use in making the request.",
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index d4622cd..82d992b 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -654,12 +654,6 @@
     ],
 }
 
-# Placeholder to add experimental flag, implementation for this is
-# pending in a separate CL.
-dart_annotations = {
-  'Element.webkitMatchesSelector': ['@Experimental'],
-}
-
 _indexed_db_annotations = [
   "@SupportedBrowser(SupportedBrowser.CHROME)",
   "@SupportedBrowser(SupportedBrowser.FIREFOX, '15')",
@@ -687,6 +681,12 @@
 
 _history_annotations = _all_but_ie9_annotations
 
+_no_ie_annotations = [
+  "@SupportedBrowser(SupportedBrowser.CHROME)",
+  "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+  "@SupportedBrowser(SupportedBrowser.SAFARI)",
+]
+
 _performance_annotations = [
   "@SupportedBrowser(SupportedBrowser.CHROME)",
   "@SupportedBrowser(SupportedBrowser.FIREFOX)",
@@ -698,6 +698,8 @@
   "@Experimental",
 ]
 
+_svg_annotations = _all_but_ie9_annotations;
+
 _web_sql_annotations = [
   "@SupportedBrowser(SupportedBrowser.CHROME)",
   "@SupportedBrowser(SupportedBrowser.SAFARI)",
@@ -734,6 +736,9 @@
   'DOMWindow.webkitNotifications': _webkit_experimental_annotations,
   'DOMWindow.webkitRequestFileSystem': _file_system_annotations,
   'DOMWindow.webkitResolveLocalFileSystemURL': _file_system_annotations,
+  # Placeholder to add experimental flag, implementation for this is
+  # pending in a separate CL.
+  'Element.webkitMatchesSelector': ['@Experimental()'],
   'Element.webkitCreateShadowRoot': [
     "@SupportedBrowser(SupportedBrowser.CHROME, '25')",
     "@Experimental",
@@ -759,21 +764,13 @@
     "@SupportedBrowser(SupportedBrowser.SAFARI)",
   ],
   'HTMLKeygenElement': _webkit_experimental_annotations,
-  'HTMLMeterElement': [
-    "@SupportedBrowser(SupportedBrowser.CHROME)",
-    "@SupportedBrowser(SupportedBrowser.FIREFOX)",
-    "@SupportedBrowser(SupportedBrowser.SAFARI)",
-  ],
+  'HTMLMeterElement': _no_ie_annotations,
   'HTMLObjectElement': [
     "@SupportedBrowser(SupportedBrowser.CHROME)",
-    "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+    "@SupportedBrowser(SupportedBrowser.IE)",
     "@SupportedBrowser(SupportedBrowser.SAFARI)",
   ],
-  'HTMLOutputElement': [
-    "@SupportedBrowser(SupportedBrowser.CHROME)",
-    "@SupportedBrowser(SupportedBrowser.FIREFOX)",
-    "@SupportedBrowser(SupportedBrowser.SAFARI)",
-  ],
+  'HTMLOutputElement': _no_ie_annotations,
   'HTMLProgressElement': _all_but_ie9_annotations,
   'HTMLShadowElement': [
     "@SupportedBrowser(SupportedBrowser.CHROME, '25')",
@@ -804,6 +801,36 @@
   'SpeechRecognitionError': _speech_recognition_annotations,
   'SpeechRecognitionEvent': _speech_recognition_annotations,
   'SpeechRecognitionResult': _speech_recognition_annotations,
+  'SVGAltGlyphElement': _no_ie_annotations,
+  'SVGAnimateElement': _no_ie_annotations,
+  'SVGAnimateMotionElement': _no_ie_annotations,
+  'SVGAnimateTransformElement': _no_ie_annotations,
+  'SVGFEBlendElement': _svg_annotations,
+  'SVGFEColorMatrixElement': _svg_annotations,
+  'SVGFEComponentTransferElement': _svg_annotations,
+  'SVGFEConvolveMatrixElement': _svg_annotations,
+  'SVGFEDiffuseLightingElement': _svg_annotations,
+  'SVGFEDisplacementMapElement': _svg_annotations,
+  'SVGFEDistantLightElement': _svg_annotations,
+  'SVGFEFloodElement': _svg_annotations,
+  'SVGFEFuncAElement': _svg_annotations,
+  'SVGFEFuncBElement': _svg_annotations,
+  'SVGFEFuncGElement': _svg_annotations,
+  'SVGFEFuncRElement': _svg_annotations,
+  'SVGFEGaussianBlurElement': _svg_annotations,
+  'SVGFEImageElement': _svg_annotations,
+  'SVGFEMergeElement': _svg_annotations,
+  'SVGFEMergeNodeElement': _svg_annotations,
+  'SVGFEMorphology': _svg_annotations,
+  'SVGFEOffsetElement': _svg_annotations,
+  'SVGFEPointLightElement': _svg_annotations,
+  'SVGFESpecularLightingElement': _svg_annotations,
+  'SVGFESpotLightElement': _svg_annotations,
+  'SVGFETileElement': _svg_annotations,
+  'SVGFETurbulenceElement': _svg_annotations,
+  'SVGFilterElement': _svg_annotations,
+  'SVGForeignObjectElement': _no_ie_annotations,
+  'SVGSetElement': _no_ie_annotations,
   'SQLTransaction': _web_sql_annotations,
   'SQLTransactionSync': _web_sql_annotations,
   'WebGLRenderingContext': _webgl_annotations,
diff --git a/tools/dom/scripts/htmldartgenerator.py b/tools/dom/scripts/htmldartgenerator.py
index dccbf03..2b2b084 100644
--- a/tools/dom/scripts/htmldartgenerator.py
+++ b/tools/dom/scripts/htmldartgenerator.py
@@ -34,11 +34,16 @@
 
   def EmitSupportCheck(self):
     if self.HasSupportCheck():
-      support_check = self.GetSupportCheck()
+      check = self.GetSupportCheck()
+      if type(check) != tuple:
+        signature = 'get supported'
+      else:
+        signature = check[0]
+        check = check[1]
       self._members_emitter.Emit('\n'
           '  /// Checks if this type is supported on the current platform.\n'
-          '  static bool get supported => $SUPPORT_CHECK;\n',
-          SUPPORT_CHECK=support_check)
+          '  static bool $SIGNATURE => $SUPPORT_CHECK;\n',
+          SIGNATURE=signature, SUPPORT_CHECK=check)
 
   def EmitEventGetter(self, events_class_name):
     self._members_emitter.Emit(
diff --git a/tools/dom/scripts/htmleventgenerator.py b/tools/dom/scripts/htmleventgenerator.py
index 8c351a4..4fd609b 100644
--- a/tools/dom/scripts/htmleventgenerator.py
+++ b/tools/dom/scripts/htmleventgenerator.py
@@ -390,13 +390,15 @@
 
     for event_info in events:
       (dom_name, html_name, event_type) = event_info
+      annotation_name = dom_name + 'Event'
 
       # If we're using a different provider, then don't declare one.
       if self._GetEventRedirection(interface, html_name, event_type):
         continue
 
       annotations = FormatAnnotationsAndComments(
-          GetAnnotationsAndComments(library_name, interface.id, dom_name), '  ')
+          GetAnnotationsAndComments(library_name, interface.id,
+                                    annotation_name), '  ')
 
       members_emitter.Emit(
           "\n"
@@ -416,6 +418,7 @@
     for event_info in events:
       (dom_name, html_name, event_type) = event_info
       getter_name = 'on%s%s' % (html_name[:1].upper(), html_name[1:])
+      annotation_name = 'on' + dom_name
 
       # If the provider is declared elsewhere, point to that.
       redirection = self._GetEventRedirection(interface, html_name, event_type)
@@ -425,7 +428,8 @@
         provider = html_name + 'Event'
 
       annotations = FormatAnnotationsAndComments(
-          GetAnnotationsAndComments(library_name, interface.id, dom_name), '  ')
+          GetAnnotationsAndComments(library_name, interface.id,
+                                    annotation_name), '  ')
 
       members_emitter.Emit(
           "\n"
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index 6fb4c86..69b90af 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -16,15 +16,7 @@
     'DOMFormData': 'FormData',
     'DOMURL': 'Url',
     'DOMWindow': 'Window',
-    'HTMLAppletElement' : '_AppletElement',
-    'HTMLBaseFontElement' : '_BaseFontElement',
-    'HTMLDirectoryElement' : '_DirectoryElement',
     'HTMLDocument' : 'HtmlDocument',
-    'HTMLFontElement' : '_FontElement',
-    'HTMLFrameElement' : '_FrameElement',
-    'HTMLFrameSetElement' : '_FrameSetElement',
-    'HTMLMarqueeElement' : '_MarqueeElement',
-    'IDBAny': '_Any', # Suppressed, but needs to exist for Dartium.
     'IDBFactory': 'IdbFactory', # Manual to avoid name conflicts.
     'NavigatorUserMediaErrorCallback': '_NavigatorUserMediaErrorCallback',
     'NavigatorUserMediaSuccessCallback': '_NavigatorUserMediaSuccessCallback',
@@ -46,6 +38,42 @@
     'XMLHttpRequestUpload': 'HttpRequestUpload',
 })
 
+# Interfaces that are suppressed, but need to still exist for Dartium and to
+# properly wrap DOM objects if/when encountered.
+_removed_html_interfaces = [
+  'HTMLAppletElement',
+  'HTMLBaseFontElement',
+  'HTMLDirectoryElement',
+  'HTMLFontElement',
+  'HTMLFrameElement',
+  'HTMLFrameSetElement',
+  'HTMLMarqueeElement',
+  'IDBAny',
+  'SVGAltGlyphDefElement', # Webkit only.
+  'SVGAltGlyphItemElement', # Webkit only.
+  'SVGAnimateColorElement', # Deprecated. Use AnimateElement instead.
+  'SVGComponentTransferFunctionElement', # Currently not supported anywhere.
+  'SVGCursorElement', # Webkit only.
+  'SVGGradientElement', # Currently not supported anywhere.
+  'SVGFEDropShadowElement', # Webkit only for the following:
+  'SVGFontElement',
+  'SVGFontFaceElement',
+  'SVGFontFaceFormatElement',
+  'SVGFontFaceNameElement',
+  'SVGFontFaceSrcElement',
+  'SVGFontFaceUriElement',
+  'SVGGlyphElement',
+  'SVGGlyphRefElement',
+  'SVGHKernElement',
+  'SVGMissingGlyphElement',
+  'SVGMPathElement',
+  'SVGTRefElement',
+  'SVGVKernElement',
+]
+
+for interface in _removed_html_interfaces:
+  html_interface_renames[interface] = '_' + interface
+
 # Members from the standard dom that should not be exposed publicly in dart:html
 # but need to be exposed internally to implement dart:html on top of a standard
 # browser.
diff --git a/tools/dom/scripts/idlparser.py b/tools/dom/scripts/idlparser.py
index fa90576..a3ee82f 100755
--- a/tools/dom/scripts/idlparser.py
+++ b/tools/dom/scripts/idlparser.py
@@ -68,9 +68,15 @@
       return syntax_switch(
         # Web IDL:
         OR(Module, Interface, ExceptionDef, TypeDef, ImplStmt,
-           ValueTypeDef, Const),
+           ValueTypeDef, Const, Enum),
         # WebKit:
-        OR(Module, Interface))
+        OR(Module, Interface, Enum))
+
+    def Enum():
+      def StringLiteral():
+        return re.compile(r'"\w+"')
+
+      return ['enum', Id, '{', MAYBE(MANY(StringLiteral, ',')), '}', ';']
 
     def Module():
       return syntax_switch(
diff --git a/tools/dom/scripts/monitored.py b/tools/dom/scripts/monitored.py
index aa26502..e90330a 100644
--- a/tools/dom/scripts/monitored.py
+++ b/tools/dom/scripts/monitored.py
@@ -29,6 +29,9 @@
     self._used_keys.add(key)
     return self._map[key]
 
+  def __setitem__(self, key, value):
+    self._map[key] = value
+
   def __contains__(self, key):
     self._used_keys.add(key)
     return key in self._map
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 78b1934c..a4ffa6f 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -69,40 +69,6 @@
     'WorkerContext.indexedDB',
     ])
 
-js_support_checks = {
-  'ArrayBuffer': "JS('bool', 'typeof window.ArrayBuffer != \"undefined\"')",
-  'Database': "JS('bool', '!!(window.openDatabase)')",
-  'DOMApplicationCache': "JS('bool', '!!(window.applicationCache)')",
-  'DOMFileSystem': "JS('bool', '!!(window.webkitRequestFileSystem)')",
-  'HashChangeEvent': "Event._isTypeSupported('HashChangeEvent')",
-  'HTMLContentElement': "Element.isTagSupported('content')",
-  'HTMLDataListElement': "Element.isTagSupported('datalist')",
-  'HTMLDetailsElement': "Element.isTagSupported('details')",
-  'HTMLEmbedElement': "Element.isTagSupported('embed')",
-  # IE creates keygen as Block elements
-  'HTMLKeygenElement': "Element.isTagSupported('keygen') "
-      "&& (new Element.tag('keygen') is KeygenElement)",
-  'HTMLMeterElement': "Element.isTagSupported('meter')",
-  'HTMLObjectElement': "Element.isTagSupported('object')",
-  'HTMLOutputElement': "Element.isTagSupported('output')",
-  'HTMLProgressElement': "Element.isTagSupported('progress')",
-  'HTMLShadowElement': "Element.isTagSupported('shadow')",
-  'HTMLTrackElement': "Element.isTagSupported('track')",
-  'MediaStreamEvent': "Event._isTypeSupported('MediaStreamEvent')",
-  'MediaStreamTrackEvent': "Event._isTypeSupported('MediaStreamTrackEvent')",
-  'NotificationCenter': "JS('bool', '!!(window.webkitNotifications)')",
-  'Performance': "JS('bool', '!!(window.performance)')",
-  'SpeechRecognition': "JS('bool', '!!(window.SpeechRecognition || "
-      "window.webkitSpeechRecognition)')",
-  'XMLHttpRequestProgressEvent':
-      "Event._isTypeSupported('XMLHttpRequestProgressEvent')",
-  'WebGLRenderingContext': "JS('bool', '!!(window.WebGLRenderingContext)')",
-  'WebKitCSSMatrix': "JS('bool', '!!(window.WebKitCSSMatrix)')",
-  'WebKitPoint': "JS('bool', '!!(window.WebKitPoint)')",
-  'WebSocket': "JS('bool', 'typeof window.WebSocket != \"undefined\"')",
-  'XSLTProcessor': "JS('bool', '!!(window.XSLTProcessor)')",
-}
-
 # Classes that offer only static methods, and therefore we should suppress
 # constructor creation.
 _static_classes = set(['Url'])
@@ -140,122 +106,139 @@
     return info
 
 _html_element_constructors = {
-  'AnchorElement' :
+  'HTMLAnchorElement' :
     ElementConstructorInfo(tag='a', opt_params=[('DOMString', 'href')]),
-  'AreaElement': 'area',
-  'ButtonElement': 'button',
-  'BRElement': 'br',
-  'BaseElement': 'base',
-  'BodyElement': 'body',
-  'ButtonElement': 'button',
-  'CanvasElement':
+  'HTMLAreaElement': 'area',
+  'HTMLButtonElement': 'button',
+  'HTMLBRElement': 'br',
+  'HTMLBaseElement': 'base',
+  'HTMLBodyElement': 'body',
+  'HTMLButtonElement': 'button',
+  'HTMLCanvasElement':
     ElementConstructorInfo(tag='canvas',
                            opt_params=[('int', 'width'), ('int', 'height')]),
-  'ContentElement': 'content',
-  'DataListElement': 'datalist',
-  'DListElement': 'dl',
-  'DetailsElement': 'details',
-  'DivElement': 'div',
-  'EmbedElement': 'embed',
-  'FieldSetElement': 'fieldset',
-  'FormElement': 'form',
-  'HRElement': 'hr',
-  'HeadElement': 'head',
-  'HeadingElement': [ElementConstructorInfo('h1'),
+  'HTMLContentElement': 'content',
+  'HTMLDataListElement': 'datalist',
+  'HTMLDListElement': 'dl',
+  'HTMLDetailsElement': 'details',
+  'HTMLDivElement': 'div',
+  'HTMLEmbedElement': 'embed',
+  'HTMLFieldSetElement': 'fieldset',
+  'HTMLFormElement': 'form',
+  'HTMLHRElement': 'hr',
+  'HTMLHeadElement': 'head',
+  'HTMLHeadingElement': [ElementConstructorInfo('h1'),
                      ElementConstructorInfo('h2'),
                      ElementConstructorInfo('h3'),
                      ElementConstructorInfo('h4'),
                      ElementConstructorInfo('h5'),
                      ElementConstructorInfo('h6')],
-  'HtmlElement': 'html',
-  'IFrameElement': 'iframe',
-  'ImageElement':
+  'HTMLHtmlElement': 'html',
+  'HTMLIFrameElement': 'iframe',
+  'HTMLImageElement':
     ElementConstructorInfo(tag='img',
                            opt_params=[('DOMString', 'src'),
                                        ('int', 'width'), ('int', 'height')]),
-  'KeygenElement': 'keygen',
-  'LIElement': 'li',
-  'LabelElement': 'label',
-  'LegendElement': 'legend',
-  'LinkElement': 'link',
-  'MapElement': 'map',
-  'MenuElement': 'menu',
-  'MeterElement': 'meter',
-  'OListElement': 'ol',
-  'ObjectElement': 'object',
-  'OptGroupElement': 'optgroup',
-  'OutputElement': 'output',
-  'ParagraphElement': 'p',
-  'ParamElement': 'param',
-  'PreElement': 'pre',
-  'ProgressElement': 'progress',
-  'ScriptElement': 'script',
-  'SelectElement': 'select',
-  'SourceElement': 'source',
-  'SpanElement': 'span',
-  'StyleElement': 'style',
-  'TableCaptionElement': 'caption',
-  'TableCellElement': 'td',
-  'TableColElement': 'col',
-  'TableElement': 'table',
-  'TableRowElement': 'tr',
-  #'TableSectionElement'  <thead> <tbody> <tfoot>
-  'TextAreaElement': 'textarea',
-  'TitleElement': 'title',
-  'TrackElement': 'track',
-  'UListElement': 'ul',
-  'VideoElement': 'video'
+  'HTMLKeygenElement': 'keygen',
+  'HTMLLIElement': 'li',
+  'HTMLLabelElement': 'label',
+  'HTMLLegendElement': 'legend',
+  'HTMLLinkElement': 'link',
+  'HTMLMapElement': 'map',
+  'HTMLMenuElement': 'menu',
+  'HTMLMeterElement': 'meter',
+  'HTMLOListElement': 'ol',
+  'HTMLObjectElement': 'object',
+  'HTMLOptGroupElement': 'optgroup',
+  'HTMLOutputElement': 'output',
+  'HTMLParagraphElement': 'p',
+  'HTMLParamElement': 'param',
+  'HTMLPreElement': 'pre',
+  'HTMLProgressElement': 'progress',
+  'HTMLScriptElement': 'script',
+  'HTMLSelectElement': 'select',
+  'HTMLSourceElement': 'source',
+  'HTMLSpanElement': 'span',
+  'HTMLStyleElement': 'style',
+  'HTMLTableCaptionElement': 'caption',
+  'HTMLTableCellElement': 'td',
+  'HTMLTableColElement': 'col',
+  'HTMLTableElement': 'table',
+  'HTMLTableRowElement': 'tr',
+  #'HTMLTableSectionElement'  <thead> <tbody> <tfoot>
+  'HTMLTextAreaElement': 'textarea',
+  'HTMLTitleElement': 'title',
+  'HTMLTrackElement': 'track',
+  'HTMLUListElement': 'ul',
+  'HTMLVideoElement': 'video'
 }
 
 _svg_element_constructors = {
-  'AElement': 'a',
-  'AnimateColorElement': 'animateColor',
-  'AnimateElement': 'animate',
-  'AnimateMotionElement': 'animateMotion',
-  'AnimateTransformElement': 'animateTransform',
-  'AnimationElement': 'animation',
-  'CircleElement': 'circle',
-  'ClipPathElement': 'clipPath',
-  'CursorElement': 'cursor',
-  'DefsElement': 'defs',
-  'DescElement': 'desc',
-  'EllipseElement': 'ellipse',
-  'FilterElement': 'filter',
-  'FontElement': 'font',
-  'FontFaceElement': 'font-face',
-  'FontFaceFormatElement': 'font-face-format',
-  'FontFaceNameElement': 'font-face-name',
-  'FontFaceSrcElement': 'font-face-src',
-  'FontFaceUriElement': 'font-face-uri',
-  'ForeignObjectElement': 'foreignObject',
-  'GlyphElement': 'glyph',
-  'GElement': 'g',
-  'HKernElement': 'hkern',
-  'ImageElement': 'image',
-  'LinearGradientElement': 'linearGradient',
-  'LineElement': 'line',
-  'MarkerElement': 'marker',
-  'MaskElement': 'mask',
-  'MPathElement': 'mpath',
-  'PathElement': 'path',
-  'PatternElement': 'pattern',
-  'PolygonElement': 'polygon',
-  'PolylineElement': 'polyline',
-  'RadialGradientElement': 'radialGradient',
-  'RectElement': 'rect',
-  'ScriptElement': 'script',
-  'SetElement': 'set',
-  'StopElement': 'stop',
-  'StyleElement': 'style',
-  'SwitchElement': 'switch',
-  'SymbolElement': 'symbol',
-  'TextElement': 'text',
-  'TitleElement': 'title',
-  'TRefElement': 'tref',
-  'TSpanElement': 'tspan',
-  'UseElement': 'use',
-  'ViewElement': 'view',
-  'VKernElement': 'vkern',
+  'SVGAElement': 'a',
+  'SVGAltGlyphElement': 'altGlyph',
+  'SVGAnimateElement': 'animate',
+  'SVGAnimateMotionElement': 'animateMotion',
+  'SVGAnimateTransformElement': 'animateTransform',
+  'SVGAnimationElement': 'animation',
+  'SVGCircleElement': 'circle',
+  'SVGClipPathElement': 'clipPath',
+  'SVGCursorElement': 'cursor',
+  'SVGDefsElement': 'defs',
+  'SVGDescElement': 'desc',
+  'SVGEllipseElement': 'ellipse',
+  'SVGFEBlendElement': 'feBlend',
+  'SVGFEColorMatrixElement': 'feColorMatrix',
+  'SVGFEComponentTransferElement': 'feComponentTransfer',
+  'SVGFEConvolveMatrixElement': 'feConvolveMatrix',
+  'SVGFEDiffuseLightingElement': 'feDiffuseLighting',
+  'SVGFEDisplacementMapElement': 'feDisplacementMap',
+  'SVGFEDistantLightElement': 'feDistantLight',
+  'SVGFEFloodElement': 'feFlood',
+  'SVGFEFuncAElement': 'feFuncA',
+  'SVGFEFuncBElement': 'feFuncB',
+  'SVGFEFuncGElement': 'feFuncG',
+  'SVGFEFuncRElement': 'feFuncR',
+  'SVGFEGaussianBlurElement': 'feGaussianBlur',
+  'SVGFEImageElement': 'feImage',
+  'SVGFEMergeElement': 'feMerge',
+  'SVGFEMergeNodeElement': 'feMergeNode',
+  'SVGFEMorphology': 'feMorphology',
+  'SVGFEOffsetElement': 'feOffset',
+  'SVGFEPointLightElement': 'fePointLight',
+  'SVGFESpecularLightingElement': 'feSpecularLighting',
+  'SVGFESpotLightElement': 'feSpotLight',
+  'SVGFETileElement': 'feTile',
+  'SVGFETurbulenceElement': 'feTurbulence',
+  'SVGFilterElement': 'filter',
+  'SVGForeignObjectElement': 'foreignObject',
+  'SVGGlyphElement': 'glyph',
+  'SVGGElement': 'g',
+  'SVGHKernElement': 'hkern',
+  'SVGImageElement': 'image',
+  'SVGLinearGradientElement': 'linearGradient',
+  'SVGLineElement': 'line',
+  'SVGMarkerElement': 'marker',
+  'SVGMaskElement': 'mask',
+  'SVGMPathElement': 'mpath',
+  'SVGPathElement': 'path',
+  'SVGPatternElement': 'pattern',
+  'SVGPolygonElement': 'polygon',
+  'SVGPolylineElement': 'polyline',
+  'SVGRadialGradientElement': 'radialGradient',
+  'SVGRectElement': 'rect',
+  'SVGScriptElement': 'script',
+  'SVGSetElement': 'set',
+  'SVGStopElement': 'stop',
+  'SVGStyleElement': 'style',
+  'SVGSwitchElement': 'switch',
+  'SVGSymbolElement': 'symbol',
+  'SVGTextElement': 'text',
+  'SVGTitleElement': 'title',
+  'SVGTRefElement': 'tref',
+  'SVGTSpanElement': 'tspan',
+  'SVGUseElement': 'use',
+  'SVGViewElement': 'view',
+  'SVGVKernElement': 'vkern',
 }
 
 _element_constructors = {
@@ -300,6 +283,95 @@
   return infos
 
 # ------------------------------------------------------------------------------
+def SvgSupportStr(tagName):
+  return 'Svg%s' % ElemSupportStr(tagName)
+
+def ElemSupportStr(tagName):
+  return "Element.isTagSupported('%s')" % tagName
+
+_js_support_checks_basic_element_with_constructors = [
+  'HTMLContentElement',
+  'HTMLDataListElement',
+  'HTMLDetailsElement',
+  'HTMLEmbedElement',
+  'HTMLMeterElement',
+  'HTMLObjectElement',
+  'HTMLOutputElement',
+  'HTMLProgressElement',
+  'HTMLTrackElement',
+]
+
+_js_support_checks_additional_element = [
+  # IE creates keygen as Block elements
+  'HTMLKeygenElement',
+  'SVGAltGlyphElement',
+  'SVGAnimateElement',
+  'SVGAnimateMotionElement',
+  'SVGAnimateTransformElement',
+  'SVGCursorElement',
+  'SVGFEBlendElement',
+  'SVGFEColorMatrixElement',
+  'SVGFEComponentTransferElement',
+  'SVGFEConvolveMatrixElement',
+  'SVGFEDiffuseLightingElement',
+  'SVGFEDisplacementMapElement',
+  'SVGFEDistantLightElement',
+  'SVGFEFloodElement',
+  'SVGFEFuncAElement',
+  'SVGFEFuncBElement',
+  'SVGFEFuncGElement',
+  'SVGFEFuncRElement',
+  'SVGFEGaussianBlurElement',
+  'SVGFEImageElement',
+  'SVGFEMergeElement',
+  'SVGFEMergeNodeElement',
+  'SVGFEMorphology',
+  'SVGFEOffsetElement',
+  'SVGFEPointLightElement',
+  'SVGFESpecularLightingElement',
+  'SVGFESpotLightElement',
+  'SVGFETileElement',
+  'SVGFETurbulenceElement',
+  'SVGFilterElement',
+  'SVGForeignObjectElement',
+  'SVGSetElement',
+]
+
+js_support_checks = dict({
+    'ArrayBuffer': "JS('bool', 'typeof window.ArrayBuffer != \"undefined\"')",
+    'Database': "JS('bool', '!!(window.openDatabase)')",
+    'DOMApplicationCache': "JS('bool', '!!(window.applicationCache)')",
+    'DOMFileSystem': "JS('bool', '!!(window.webkitRequestFileSystem)')",
+    'HashChangeEvent': "Event._isTypeSupported('HashChangeEvent')",
+    'HTMLShadowElement': ElemSupportStr('shadow'),
+    'MediaStreamEvent': "Event._isTypeSupported('MediaStreamEvent')",
+    'MediaStreamTrackEvent': "Event._isTypeSupported('MediaStreamTrackEvent')",
+    'NotificationCenter': "JS('bool', '!!(window.webkitNotifications)')",
+    'Performance': "JS('bool', '!!(window.performance)')",
+    'SpeechRecognition': "JS('bool', '!!(window.SpeechRecognition || "
+        "window.webkitSpeechRecognition)')",
+    'SVGExternalResourcesRequired': ('supported(SvgElement element)',
+        "JS('bool', '#.externalResourcesRequired !== undefined && "
+        "#.externalResourcesRequired.animVal !== undefined', "
+        "element, element)"),
+    'SVGLangSpace': ('supported(SvgElement element)',
+        "JS('bool', '#.xmlspace !== undefined && #.xmllang !== undefined', "
+        "element, element)"),
+    'TouchList': "JS('bool', '!!document.createTouchList')",
+    'XMLHttpRequestProgressEvent':
+        "Event._isTypeSupported('XMLHttpRequestProgressEvent')",
+    'WebGLRenderingContext': "JS('bool', '!!(window.WebGLRenderingContext)')",
+    'WebKitCSSMatrix': "JS('bool', '!!(window.WebKitCSSMatrix)')",
+    'WebKitPoint': "JS('bool', '!!(window.WebKitPoint)')",
+    'WebSocket': "JS('bool', 'typeof window.WebSocket != \"undefined\"')",
+    'XSLTProcessor': "JS('bool', '!!(window.XSLTProcessor)')",
+  }.items() +
+  dict((key,
+        SvgSupportStr(_svg_element_constructors[key]) if key.startswith('SVG')
+            else ElemSupportStr(_html_element_constructors[key])) for key in
+    _js_support_checks_basic_element_with_constructors +
+    _js_support_checks_additional_element).items())
+# ------------------------------------------------------------------------------
 
 class HtmlDartInterfaceGenerator(object):
   """Generates dart interface and implementation for the DOM IDL interface."""
@@ -359,7 +431,7 @@
       factory_provider = interface_name
 
     # HTML Elements and SVG Elements have convenience constructors.
-    infos = ElementConstructorInfos(interface_name,
+    infos = ElementConstructorInfos(self._interface.id,
         _element_constructors[self._library_name], factory_provider_name=
         _factory_ctr_strings[self._library_name]['provider_name'])
 
@@ -521,6 +593,19 @@
     return self._interface.doc_js_name in js_support_checks
 
   def GetSupportCheck(self):
+    """Return a tuple of the support check function signature and the support
+    test itself. If no parameters are supplied, we assume the default."""
+    if self._interface.doc_js_name in _js_support_checks_additional_element:
+      if self._interface.doc_js_name in _svg_element_constructors:
+        lib_prefix = 'Svg'
+        constructors = _svg_element_constructors
+      else:
+        lib_prefix = ''
+        constructors = _html_element_constructors
+      return (js_support_checks.get(self._interface.doc_js_name) +
+          " && (new %sElement.tag('%s') is %s)" % (lib_prefix,
+        constructors[self._interface.doc_js_name],
+        self._renamer.RenameInterface(self._interface)))
     return js_support_checks.get(self._interface.doc_js_name)
 
   def GenerateCustomFactory(self, constructor_info):
diff --git a/tools/dom/scripts/systemnative.py b/tools/dom/scripts/systemnative.py
index df82ca7..06e27a9 100644
--- a/tools/dom/scripts/systemnative.py
+++ b/tools/dom/scripts/systemnative.py
@@ -235,7 +235,11 @@
 
   def GetSupportCheck(self):
     # Assume that everything is supported on Dartium.
-    return 'true'
+    value = js_support_checks.get(self._interface.doc_js_name)
+    if type(value) == tuple:
+      return (value[0], 'true')
+    else:
+      return 'true'
 
   def FinishInterface(self):
     self._GenerateCPPHeader()
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index f87c1b2..20350cc 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -5,6 +5,7 @@
 // DO NOT EDIT
 // Auto-generated dart:html library.
 
+/// The Dart HTML library.
 library dart.dom.html;
 
 import 'dart:async';
@@ -49,8 +50,14 @@
 part '$AUXILIARY_DIR/_ListIterators.dart';
 
 
+/**
+ * The top-level Window object.
+ */
 Window get window => JS('Window', 'window');
 
+/**
+ * The top-level Document object.
+ */
 HtmlDocument get document => JS('Document', 'document');
 
 Element query(String selector) => document.query(selector);
diff --git a/tools/dom/templates/html/dart2js/impl_Console.darttemplate b/tools/dom/templates/html/dart2js/impl_Console.darttemplate
index dbd7bc3..0bc592c 100644
--- a/tools/dom/templates/html/dart2js/impl_Console.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_Console.darttemplate
@@ -79,8 +79,8 @@
       JS('void', 'console.time(#)', title) : null;
 
   @DomName('Console.timeEnd')
-  void timeEnd(String title, Object arg) => _isConsoleDefined ?
-      JS('void', 'console.timeEnd(#, #)', title, arg) : null;
+  void timeEnd(String timerName) => _isConsoleDefined ?
+      JS('void', 'console.timeEnd(#)', timerName) : null;
 
   @DomName('Console.timeStamp')
   void timeStamp(Object arg) => _isConsoleDefined ?
diff --git a/tools/dom/templates/html/dart2js/impl_HTMLTableElement.darttemplate b/tools/dom/templates/html/dart2js/impl_HTMLTableElement.darttemplate
index 52f7436..b41ec58 100644
--- a/tools/dom/templates/html/dart2js/impl_HTMLTableElement.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_HTMLTableElement.darttemplate
@@ -12,7 +12,7 @@
       return this._createTBody();
     }
     var tbody = new Element.tag('tbody');
-    this.elements.add(tbody);
+    this.children.add(tbody);
     return tbody;
   }
 
diff --git a/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate b/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate
index 7ca2b26..d39c3c9 100644
--- a/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate
@@ -22,6 +22,15 @@
   }
 $!MEMBERS
 
+  // TODO(amouravski): Move this documentation out of thise template files and
+  // put it into docs.json. Remember to add @DomName here.
+  /**
+   * The X coordinate of the mouse pointer in target node coordinates.
+   *
+   * This value may vary between platforms if the target node moves
+   * after the event has fired or if the element has CSS transforms affecting
+   * it.
+   */
   int get offsetX {
   if (JS('bool', '!!#.offsetX', this)) {
       return JS('int', '#.offsetX', this);
@@ -36,6 +45,13 @@
     }
   }
 
+  /**
+   * The Y coordinate of the mouse pointer in target node coordinates.
+   *
+   * This value may vary between platforms if the target node moves
+   * after the event has fired or if the element has CSS transforms affecting
+   * it.
+   */
   int get offsetY {
     if (JS('bool', '!!#.offsetY', this)) {
       return JS('int', '#.offsetY', this);
diff --git a/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate b/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
index 13edffb..4bfdfbc 100644
--- a/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
+++ b/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
@@ -13,15 +13,6 @@
   factory $CLASSNAME.svg(String svgContent) =>
       _$(CLASSNAME)FactoryProvider.createDocumentFragment_svg(svgContent);
 
-  @deprecated
-  List<Element> get elements => this.children;
-
-  // TODO: The type of value should be Collection<Element>. See http://b/5392897
-  @deprecated
-  void set elements(value) {
-    this.children = value;
-  }
-
 $if DART2JS
   // Native field is used only by Dart code so does not lead to instantiation
   // of native classes
@@ -68,14 +59,27 @@
     this.nodes.addAll(nodes);
   }
 
+  /**
+   * Adds the specified element after the last child of this
+   * document fragment.
+   */
   void append(Element element) {
     this.children.add(element);
   }
 
+  /**
+   * Adds the specified text as a text node after the last child of this
+   * document fragment.
+   */
   void appendText(String text) {
     this.nodes.add(new Text(text));
   }
 
+
+  /**
+   * Parses the specified text as HTML and adds the resulting node after the
+   * last child of this document fragment.
+   */
   void appendHtml(String text) {
     this.nodes.add(new DocumentFragment.html(text));
   }
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 340774c..c47ffe1 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -62,7 +62,7 @@
   }
 
   Iterable map(f(Element element)) {
-    return IterableMixinWorkaround.map(this, f);
+    return IterableMixinWorkaround.mapList(this, f);
   }
 
   List mappedBy(f(Element element)) {
@@ -279,7 +279,7 @@
   }
 
   Iterable map(f(Element element)) {
-    return IterableMixinWorkaround.map(this, f);
+    return IterableMixinWorkaround.mapList(this, f);
   }
 
   List mappedBy(f(Element element)) {
@@ -575,27 +575,6 @@
   }
 
   /**
-   * Deprecated, use innerHtml instead.
-   */
-  @deprecated
-  String get innerHTML => this.innerHtml;
-  @deprecated
-  void set innerHTML(String value) {
-    this.innerHtml = value;
-  }
-
-  @deprecated
-  void set elements(Collection<Element> value) {
-    this.children = value;
-  }
-
-  /**
-   * Deprecated, use [children] instead.
-   */
-  @deprecated
-  List<Element> get elements => this.children;
-
-  /**
    * List of the direct children of this element.
    *
    * This collection can be used to add and remove elements from the document.
@@ -1049,7 +1028,8 @@
   // Optimization to improve performance until the dart2js compiler inlines this
   // method.
   static dynamic createElement_tag(String tag) =>
-      JS('Element', 'document.createElement(#)', tag);
+      // Firefox may return a JS function for some types (Embed, Object).
+      JS('Element|=Object', 'document.createElement(#)', tag);
 $else
   static Element createElement_tag(String tag) =>
       document.$dom_createElement(tag);
diff --git a/tools/dom/templates/html/impl/impl_Node.darttemplate b/tools/dom/templates/html/impl/impl_Node.darttemplate
index 473f94a..63d0e49 100644
--- a/tools/dom/templates/html/impl/impl_Node.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Node.darttemplate
@@ -139,7 +139,7 @@
   }
 
   Iterable map(f(Node element)) {
-    return IterableMixinWorkaround.map(this, f);
+    return IterableMixinWorkaround.mapList(this, f);
   }
 
   List mappedBy(f(Node element)) {
diff --git a/tools/dom/templates/html/impl/impl_SVGElement.darttemplate b/tools/dom/templates/html/impl/impl_SVGElement.darttemplate
index 42ad450..c3ee680 100644
--- a/tools/dom/templates/html/impl/impl_SVGElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_SVGElement.darttemplate
@@ -45,16 +45,6 @@
     return _cssClassSet;
   }
 
-  @deprecated
-  List<Element> get elements => new FilteredElementList(this);
-
-  @deprecated
-  void set elements(Collection<Element> value) {
-    final elements = this.elements;
-    elements.clear();
-    elements.addAll(value);
-  }
-
   List<Element> get children => new FilteredElementList(this);
 
   void set children(List<Element> value) {
@@ -111,5 +101,14 @@
     throw new UnsupportedError("Cannot invoke click SVG.");
   }
 
+  /**
+   * Checks to see if the SVG element type is supported by the current platform.
+   *
+   * The tag should be a valid SVG element tag name.
+   */
+  static bool isTagSupported(String tag) {
+    var e = new $CLASSNAME.tag(tag);
+    return e is $CLASSNAME && !(e is UnknownElement);
+  }
 $!MEMBERS
 }
diff --git a/tools/dom/templates/html/impl/impl_Storage.darttemplate b/tools/dom/templates/html/impl/impl_Storage.darttemplate
index 7cde516..e4d0523 100644
--- a/tools/dom/templates/html/impl/impl_Storage.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Storage.darttemplate
@@ -4,6 +4,31 @@
 
 part of $LIBRARYNAME;
 
+/**
+ * The type used by the
+ * [Window.localStorage] and [Window.sessionStorage] properties.
+ * Storage is implemented as a Map&lt;String, String>.
+ *
+ * To store and get values, use Dart's built-in map syntax:
+ *
+ *     window.localStorage['key1'] = 'val1';
+ *     window.localStorage['key2'] = 'val2';
+ *     window.localStorage['key3'] = 'val3';
+ *     assert(window.localStorage['key3'] == 'val3');
+ *
+ * You can use [Map](http://api.dartlang.org/dart_core/Map.html) APIs
+ * such as containsValue(), clear(), and length:
+ *
+ *     assert(window.localStorage.containsValue('does not exist') == false);
+ *     window.localStorage.clear();
+ *     assert(window.localStorage.length == 0);
+ *
+ * For more examples of using this API, see
+ * [localstorage_test.dart](http://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/tests/html/localstorage_test.dart).
+ * For details on using the Map API, see the
+ * [Maps](http://www.dartlang.org/docs/library-tour/#maps-aka-dictionaries-or-hashes)
+ * section of the library tour.
+ */
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS implements Map<String, String>
     $NATIVESPEC {
 
diff --git a/tools/dom/templates/html/impl/impl_TouchList.darttemplate b/tools/dom/templates/html/impl/impl_TouchList.darttemplate
new file mode 100644
index 0000000..aa375b7
--- /dev/null
+++ b/tools/dom/templates/html/impl/impl_TouchList.darttemplate
@@ -0,0 +1,15 @@
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+part of $LIBRARYNAME;
+
+$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
+  /// NB: This constructor likely does not work as you might expect it to! This
+  /// constructor will simply fail (returning null) if you are not on a device
+  /// with touch enabled. See dartbug.com/8314.
+  factory $CLASSNAME() => document.$dom_createTouchList();
+$!MEMBERS
+}
diff --git a/tools/dom/templates/immutable_list_mixin.darttemplate b/tools/dom/templates/immutable_list_mixin.darttemplate
index 58cf40c..77fdd0d 100644
--- a/tools/dom/templates/immutable_list_mixin.darttemplate
+++ b/tools/dom/templates/immutable_list_mixin.darttemplate
@@ -30,7 +30,7 @@
       IterableMixinWorkaround.joinList(this, separator);
 
   Iterable map(f($E element)) =>
-      IterableMixinWorkaround.map(this, f);
+      IterableMixinWorkaround.mapList(this, f);
 
   List mappedBy(f($E element)) =>
       IterableMixinWorkaround.mappedByList(this, f);
diff --git a/utils/pub/command_install.dart b/utils/pub/command_install.dart
index 001ba21..4297031 100644
--- a/utils/pub/command_install.dart
+++ b/utils/pub/command_install.dart
@@ -10,14 +10,14 @@
 import 'log.dart' as log;
 import 'pub.dart';
 
-/// Handles the `install` pub command. 
+/// Handles the `install` pub command.
 class InstallCommand extends PubCommand {
   String get description => "Install the current package's dependencies.";
   String get usage => "pub install";
 
   Future onRun() {
-    return entrypoint.installDependencies().then((_) {
-      log.message("Dependencies installed!");
-    });
+    return entrypoint.installDependencies()
+        .then((_) => log.message("Dependencies installed!"))
+        .then((_) => entrypoint.validateSdkConstraints());
   }
 }
diff --git a/utils/pub/command_lish.dart b/utils/pub/command_lish.dart
index 536a3aa..1566f14 100644
--- a/utils/pub/command_lish.dart
+++ b/utils/pub/command_lish.dart
@@ -86,20 +86,19 @@
   }
 
   Future onRun() {
-    var files;
-    var packageBytesFuture = _filesToPublish.then((f) {
-      files = f;
+    var packageBytesFuture = _filesToPublish.then((files) {
       log.fine('Archiving and publishing ${entrypoint.root}.');
+
+      // Show the package contents so the user can verify they look OK.
+      var package = entrypoint.root;
+      log.message(
+          'Publishing "${package.name}" ${package.version}:\n'
+          '${generateTree(files)}');
+
       return createTarGz(files, baseDir: entrypoint.root.dir);
-    }).then(consumeInputStream);
+    }).then((stream) => stream.toBytes());
 
-    // Show the package contents so the user can verify they look OK.
-    var package = entrypoint.root;
-    log.message(
-        'Publishing "${package.name}" ${package.version}:\n'
-        '${generateTree(files)}');
-
-      // Validate the package.
+    // Validate the package.
     return _validate(packageBytesFuture.then((bytes) => bytes.length))
         .then((_) => packageBytesFuture).then(_publish);
   }
@@ -109,7 +108,7 @@
 
   /// The basenames of directories that are automatically excluded from
   /// archives.
-  final _BLACKLISTED_DIRECTORIES = const ['packages'];
+  final _BLACKLISTED_DIRS = const ['packages'];
 
   /// Returns a list of files that should be included in the published package.
   /// If this is a Git repository, this will respect .gitignore; otherwise, it
@@ -117,11 +116,8 @@
   Future<List<String>> get _filesToPublish {
     var rootDir = entrypoint.root.dir;
 
-    return Future.wait([
-      dirExists(join(rootDir, '.git')),
-      git.isInstalled
-    ]).then((results) {
-      if (results[0] && results[1]) {
+    return git.isInstalled.then((gitInstalled) {
+      if (dirExists(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",
@@ -129,27 +125,17 @@
       }
 
       return listDir(rootDir, recursive: true).then((entries) {
-        return Future.wait(entries.map((entry) {
-          return fileExists(entry).then((isFile) {
-            // Skip directories.
-            if (!isFile) return null;
-
-            // TODO(rnystrom): Making these relative will break archive
-            // creation if the cwd is ever *not* the package root directory.
-            // Should instead only make these relative right before generating
-            // the tree display (which is what really needs them to be).
-            // Make it relative to the package root.
-            return relativeTo(entry, rootDir);
-          });
-        }));
+        return entries
+            .where(fileExists) // Skip directories.
+            .map((entry) => relativeTo(entry, rootDir));
       });
-    }).then((files) => files.where((file) {
-      if (file == null || _BLACKLISTED_FILES.contains(basename(file))) {
-        return false;
-      }
+    }).then((files) => files.where(_shouldPublish).toList());
+  }
 
-      return !splitPath(file).any(_BLACKLISTED_DIRECTORIES.contains);
-    }).toList());
+  /// Returns `true` if [file] should be published.
+  bool _shouldPublish(String file) {
+    if (_BLACKLISTED_FILES.contains(basename(file))) return false;
+    return !splitPath(file).any(_BLACKLISTED_DIRS.contains);
   }
 
   /// Returns the value associated with [key] in [map]. Throws a user-friendly
diff --git a/utils/pub/command_update.dart b/utils/pub/command_update.dart
index 4757049..5c556ce 100644
--- a/utils/pub/command_update.dart
+++ b/utils/pub/command_update.dart
@@ -9,7 +9,7 @@
 import 'log.dart' as log;
 import 'pub.dart';
 
-/// Handles the `update` pub command. 
+/// Handles the `update` pub command.
 class UpdateCommand extends PubCommand {
   String get description =>
     "Update the current package's dependencies to the latest versions.";
@@ -23,6 +23,8 @@
     } else {
       future = entrypoint.updateDependencies(commandOptions.rest);
     }
-    return future.then((_) => log.message("Dependencies updated!"));
+    return future
+        .then((_) => log.message("Dependencies updated!"))
+        .then((_) => entrypoint.validateSdkConstraints());
   }
 }
diff --git a/utils/pub/command_uploader.dart b/utils/pub/command_uploader.dart
index 445b61e..a8c2100 100644
--- a/utils/pub/command_uploader.dart
+++ b/utils/pub/command_uploader.dart
@@ -58,11 +58,10 @@
       exit(exit_codes.USAGE);
     }
 
-    return new Future.immediate(null).then((_) {
+    return defer(() {
       var package = commandOptions['package'];
       if (package != null) return package;
-      return Entrypoint.load(path.current, cache)
-          .then((entrypoint) => entrypoint.root.name);
+      return new Entrypoint(path.current, cache).root.name;
     }).then((package) {
       var uploader = commandOptions.rest[0];
       return oauth2.withClient(cache, (client) {
diff --git a/utils/pub/curl_client.dart b/utils/pub/curl_client.dart
deleted file mode 100644
index 7001a17..0000000
--- a/utils/pub/curl_client.dart
+++ /dev/null
@@ -1,198 +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.
-
-library curl_client;
-
-import 'dart:async';
-import 'dart:io';
-
-import '../../pkg/http/lib/http.dart' as http;
-import 'io.dart';
-import 'log.dart' as log;
-import 'utils.dart';
-
-/// A drop-in replacement for [http.Client] that uses the `curl` command-line
-/// utility rather than [dart:io] to make requests. This class will only exist
-/// temporarily until [dart:io] natively supports requests over HTTPS.
-class CurlClient extends http.BaseClient {
-  /// The path to the `curl` executable to run.
-  ///
-  /// By default on Unix-like operating systems, this will look up `curl` on the
-  /// system path. On Windows, it will use the bundled `curl.exe`.
-  final String executable;
-
-  /// Creates a new [CurlClient] with [executable] as the path to the `curl`
-  /// executable.
-  ///
-  /// By default on Unix-like operating systems, this will look up `curl` on the
-  /// system path. On Windows, it will use the bundled `curl.exe`.
-  CurlClient([String executable])
-    : executable = executable == null ? _defaultExecutable : executable;
-
-  /// Sends a request via `curl` and returns the response.
-  Future<http.StreamedResponse> send(http.BaseRequest request) {
-    log.fine("Sending Curl request $request");
-
-    var requestStream = request.finalize();
-    return withTempDir((tempDir) {
-      var headerFile = join(tempDir, "curl-headers");
-      var arguments = _argumentsForRequest(request, headerFile);
-      var process;
-      return startProcess(executable, arguments).then((process_) {
-        process = process_;
-        return requestStream.pipe(wrapOutputStream(process.stdin));
-      }).then((_) {
-        return _waitForHeaders(process, expectBody: request.method != "HEAD");
-      }).then((_) => new File(headerFile).readAsLines())
-        .then((lines) => _buildResponse(request, process, lines));
-    });
-  }
-
-  /// Returns the list of arguments to `curl` necessary for performing
-  /// [request]. [headerFile] is the path to the file where the response headers
-  /// should be stored.
-  List<String> _argumentsForRequest(
-      http.BaseRequest request, String headerFile) {
-    // Note: This line of code gets munged by create_sdk.py to be the correct
-    // relative path to the certificate file in the SDK.
-    var pathToCertificates = "../../third_party/curl/ca-certificates.crt";
-
-    var arguments = [
-      "--dump-header", headerFile,
-      "--cacert", relativeToPub(pathToCertificates)
-    ];
-    if (request.method == 'HEAD') {
-      arguments.add("--head");
-    } else {
-      arguments.add("--request");
-      arguments.add(request.method);
-    }
-    if (request.followRedirects) {
-      arguments.add("--location");
-      arguments.add("--max-redirs");
-      arguments.add(request.maxRedirects.toString());
-    }
-    if (request.contentLength != 0)  {
-      arguments.add("--data-binary");
-      arguments.add("@-");
-    }
-
-    // Override the headers automatically added by curl. We want to make it
-    // behave as much like the dart:io client as possible.
-    var headers = {
-      'accept': '',
-      'user-agent': ''
-    };
-    request.headers.forEach((name, value) => headers[name] = value);
-    if (request.contentLength < 0) {
-      headers['content-length'] = '';
-      headers['transfer-encoding'] = 'chunked';
-    } else if (request.contentLength > 0) {
-      headers['content-length'] = request.contentLength.toString();
-    }
-
-    headers.forEach((name, value) {
-      arguments.add("--header");
-      arguments.add("$name: $value");
-    });
-    arguments.add(request.url.toString());
-
-    return arguments;
-  }
-
-  /// Returns a [Future] that completes once the `curl` [process] has finished
-  /// receiving the response headers. [expectBody] indicates that the server is
-  /// expected to send a response body (which is not the case for HEAD
-  /// requests).
-  ///
-  /// Curl prints the headers to a file and then prints the body to stdout. So,
-  /// in theory, we could read the headers as soon as we see anything appear
-  /// in stdout. However, that seems to be too early to successfully read the
-  /// file (at least on Mac). Instead, this just waits until the entire process
-  /// has completed.
-  Future _waitForHeaders(Process process, {bool expectBody}) {
-    var completer = new Completer();
-    process.onExit = (exitCode) {
-      log.io("Curl process exited with code $exitCode.");
-
-      if (exitCode == 0) {
-        completer.complete(null);
-        return;
-      }
-
-      chainToCompleter(consumeInputStream(process.stderr).then((stderrBytes) {
-        var message = new String.fromCharCodes(stderrBytes);
-        log.fine('Got error reading headers from curl: $message');
-        if (exitCode == 47) {
-          throw new RedirectLimitExceededException([]);
-        } else {
-          throw new HttpException(message);
-        }
-      }), completer);
-    };
-
-    // If there's not going to be a response body (e.g. for HEAD requests), curl
-    // prints the headers to stdout instead of the body. We want to wait until
-    // all the headers are received to read them from the header file.
-    if (!expectBody) {
-      return Future.wait([
-        consumeInputStream(process.stdout),
-        completer.future
-      ]);
-    }
-
-    return completer.future;
-  }
-
-  /// Returns a [http.StreamedResponse] from the response data printed by the
-  /// `curl` [process]. [lines] are the headers that `curl` wrote to a file.
-  http.StreamedResponse _buildResponse(
-      http.BaseRequest request, Process process, List<String> lines) {
-    // When curl follows redirects, it prints the redirect headers as well as
-    // the headers of the final request. Each block is separated by a blank
-    // line. We just care about the last block. There is one trailing empty
-    // line, though, which we don't want to consider a separator.
-    var lastBlank = lines.lastIndexOf("", lines.length - 2);
-    if (lastBlank != -1) lines.removeRange(0, lastBlank + 1);
-
-    var statusParts = lines.removeAt(0).split(" ");
-    var status = int.parse(statusParts[1]);
-    var isRedirect = status >= 300 && status < 400;
-    var reasonPhrase =
-        Strings.join(statusParts.getRange(2, statusParts.length - 2), " ");
-    var headers = {};
-    for (var line in lines) {
-      if (line.isEmpty) continue;
-      var split = split1(line, ":");
-      headers[split[0].toLowerCase()] = split[1].trim();
-    }
-    var responseStream = process.stdout;
-    if (responseStream.closed) {
-      responseStream = new ListInputStream();
-      responseStream.markEndOfStream();
-    }
-    var contentLength = -1;
-    if (headers.containsKey('content-length')) {
-      contentLength = int.parse(headers['content-length']);
-    }
-
-    return new http.StreamedResponse(
-        wrapInputStream(responseStream), status, contentLength,
-        request: request,
-        headers: headers,
-        isRedirect: isRedirect,
-        reasonPhrase: reasonPhrase);
-  }
-
-  /// The default executable to use for running curl. On Windows, this is the
-  /// path to the bundled `curl.exe`; elsewhere, this is just "curl", and we
-  /// assume it to be installed and on the user's PATH.
-  static String get _defaultExecutable {
-    if (Platform.operatingSystem != 'windows') return 'curl';
-    // Note: This line of code gets munged by create_sdk.py to be the correct
-    // relative path to curl in the SDK.
-    var pathToCurl = "../../third_party/curl/curl.exe";
-    return relativeToPub(pathToCurl);
-  }
-}
diff --git a/utils/pub/entrypoint.dart b/utils/pub/entrypoint.dart
index d562997..843d41d 100644
--- a/utils/pub/entrypoint.dart
+++ b/utils/pub/entrypoint.dart
@@ -9,6 +9,8 @@
 import 'lock_file.dart';
 import 'log.dart' as log;
 import 'package.dart';
+import 'pubspec.dart';
+import 'sdk.dart' as sdk;
 import 'system_cache.dart';
 import 'utils.dart';
 import 'version.dart';
@@ -39,16 +41,12 @@
 
   /// Packages which are either currently being asynchronously installed to the
   /// directory, or have already been installed.
-  final Map<PackageId, Future<PackageId>> _installs;
-
-  Entrypoint(this.root, this.cache)
-  : _installs = new Map<PackageId, Future<PackageId>>();
+  final _installs = new Map<PackageId, Future<PackageId>>();
 
   /// Loads the entrypoint from a package at [rootDir].
-  static Future<Entrypoint> load(String rootDir, SystemCache cache) {
-    return Package.load(null, rootDir, cache.sources).then((package) =>
-        new Entrypoint(package, cache));
-  }
+  Entrypoint(String rootDir, SystemCache cache)
+      : root = new Package.load(null, rootDir, cache.sources),
+        cache = cache;
 
   // TODO(rnystrom): Make this path configurable.
   /// The path to this "packages" directory.
@@ -70,10 +68,10 @@
     if (pendingOrCompleted != null) return pendingOrCompleted;
 
     var packageDir = join(path, id.name);
-    var future = ensureDir(dirname(packageDir)).then((_) {
-      return exists(packageDir);
-    }).then((exists) {
-      if (!exists) return;
+    var future = defer(() {
+      ensureDir(dirname(packageDir));
+      if (!dirExists(packageDir)) return;
+
       // TODO(nweiz): figure out when to actually delete the directory, and when
       // we can just re-use the existing symlink.
       log.fine("Deleting package directory for ${id.name} before install.");
@@ -100,9 +98,9 @@
   /// directory, respecting the [LockFile] if present. Returns a [Future] that
   /// completes when all dependencies are installed.
   Future installDependencies() {
-    return loadLockFile()
-      .then((lockFile) => resolveVersions(cache.sources, root, lockFile))
-      .then(_installDependencies);
+    return defer(() {
+      return resolveVersions(cache.sources, root, loadLockFile());
+    }).then(_installDependencies);
   }
 
   /// Installs the latest available versions of all dependencies of the [root]
@@ -110,19 +108,19 @@
   /// [Future] that completes when all dependencies are installed.
   Future updateAllDependencies() {
     return resolveVersions(cache.sources, root, new LockFile.empty())
-      .then(_installDependencies);
+        .then(_installDependencies);
   }
 
   /// Installs the latest available versions of [dependencies], while leaving
   /// other dependencies as specified by the [LockFile] if possible. Returns a
   /// [Future] that completes when all dependencies are installed.
   Future updateDependencies(List<String> dependencies) {
-    return loadLockFile().then((lockFile) {
-      var versionSolver = new VersionSolver(cache.sources, root, lockFile);
+    return defer(() {
+      var solver = new VersionSolver(cache.sources, root, loadLockFile());
       for (var dependency in dependencies) {
-        versionSolver.useLatestVersion(dependency);
+        solver.useLatestVersion(dependency);
       }
-      return versionSolver.solve();
+      return solver.solve();
     }).then(_installDependencies);
   }
 
@@ -139,45 +137,93 @@
       .then(_linkSecondaryPackageDirs);
   }
 
-  /// Loads the list of concrete package versions from the `pubspec.lock`, if it
-  /// exists. If it doesn't, this completes to an empty [LockFile].
-  Future<LockFile> loadLockFile() {
-    var lockFilePath = join(root.dir, 'pubspec.lock');
+  /// Traverses the root's package dependency graph and loads each of the
+  /// reached packages. This should only be called after the lockfile has been
+  /// successfully generated.
+  Future<List<Pubspec>> walkDependencies() {
+    return defer(() {
+      var lockFile = loadLockFile();
+      var group = new FutureGroup<Pubspec>();
+      var visited = new Set<String>();
 
-    log.fine("Loading lockfile.");
-    return fileExists(lockFilePath).then((exists) {
-      if (!exists) {
-        log.fine("No lock file at $lockFilePath, creating empty one.");
-        return new LockFile.empty();
+      // Include the root package in the results.
+      group.add(new Future.immediate(root.pubspec));
+
+      visitPackage(Pubspec pubspec) {
+        for (var ref in pubspec.dependencies) {
+          if (visited.contains(ref.name)) continue;
+
+          // Look up the concrete version.
+          var id = lockFile.packages[ref.name];
+
+          visited.add(ref.name);
+          var future = cache.describe(id);
+          group.add(future.then(visitPackage));
+        }
+
+        return pubspec;
       }
 
-      return readTextFile(lockFilePath).then((text) =>
-          new LockFile.parse(text, cache.sources));
+      visitPackage(root.pubspec);
+      return group.future;
     });
   }
 
+  /// Validates that the current Dart SDK version matches the SDK constraints
+  /// of every package in the dependency graph. If a package's constraint does
+  /// not match, prints an error.
+  Future validateSdkConstraints() {
+    return walkDependencies().then((pubspecs) {
+      var errors = [];
+
+      for (var pubspec in pubspecs) {
+        var sdkConstraint = pubspec.environment.sdkVersion;
+        if (!sdkConstraint.allows(sdk.version)) {
+          errors.add("- '${pubspec.name}' requires ${sdkConstraint}");
+        }
+      }
+
+      if (errors.length > 0) {
+        log.error("Some packages are not compatible with your SDK version "
+                "${sdk.version}:\n"
+            "${errors.join('\n')}\n\n"
+            "You may be able to resolve this by upgrading to the latest Dart "
+                "SDK\n"
+            "or adding a version constraint to use an older version of a "
+                "package.");
+      }
+    });
+  }
+
+  /// 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');
+    if (!fileExists(lockFilePath)) return new LockFile.empty();
+    return new LockFile.parse(readTextFile(lockFilePath), cache.sources);
+  }
+
   /// Saves a list of concrete package versions to the `pubspec.lock` file.
-  Future _saveLockFile(List<PackageId> packageIds) {
+  void _saveLockFile(List<PackageId> packageIds) {
     var lockFile = new LockFile.empty();
     for (var id in packageIds) {
       if (!id.isRoot) lockFile.packages[id.name] = id;
     }
 
     var lockFilePath = join(root.dir, 'pubspec.lock');
-    log.fine("Saving lockfile.");
-    return writeTextFile(lockFilePath, lockFile.serialize());
+    writeTextFile(lockFilePath, lockFile.serialize());
   }
 
   /// Installs a self-referential symlink in the `packages` directory that will
   /// allow a package to import its own files using `package:`.
   Future _installSelfReference(_) {
-    var linkPath = join(path, root.name);
-    return exists(linkPath).then((exists) {
+    return defer(() {
+      var linkPath = join(path, root.name);
       // Create the symlink if it doesn't exist.
-      if (exists) return;
-      return ensureDir(path).then(
-          (_) => createPackageSymlink(root.name, root.dir, linkPath,
-              isSelfLink: true));
+      if (entryExists(linkPath)) return;
+      ensureDir(path);
+      return createPackageSymlink(root.name, root.dir, linkPath,
+          isSelfLink: true);
     });
   }
 
@@ -190,8 +236,8 @@
     var testDir = join(root.dir, 'test');
     var toolDir = join(root.dir, 'tool');
     var webDir = join(root.dir, 'web');
-    return dirExists(binDir).then((exists) {
-      if (!exists) return;
+    return defer(() {
+      if (!dirExists(binDir)) return;
       return _linkSecondaryPackageDir(binDir);
     }).then((_) => _linkSecondaryPackageDirsRecursively(exampleDir))
       .then((_) => _linkSecondaryPackageDirsRecursively(testDir))
@@ -202,14 +248,14 @@
   /// Creates a symlink to the `packages` directory in [dir] and all its
   /// subdirectories.
   Future _linkSecondaryPackageDirsRecursively(String dir) {
-    return dirExists(dir).then((exists) {
-      if (!exists) return;
+    return defer(() {
+      if (!dirExists(dir)) return;
       return _linkSecondaryPackageDir(dir)
-        .then((_) => _listDirWithoutPackages(dir))
-        .then((files) {
+          .then((_) => _listDirWithoutPackages(dir))
+          .then((files) {
         return Future.wait(files.map((file) {
-          return dirExists(file).then((isDir) {
-            if (!isDir) return;
+          return defer(() {
+            if (!dirExists(file)) return;
             return _linkSecondaryPackageDir(file);
           });
         }));
@@ -224,8 +270,8 @@
     return listDir(dir).then((files) {
       return Future.wait(files.map((file) {
         if (basename(file) == 'packages') return new Future.immediate([]);
-        return dirExists(file).then((isDir) {
-          if (!isDir) return [];
+        return defer(() {
+          if (!dirExists(file)) return [];
           return _listDirWithoutPackages(file);
         }).then((subfiles) {
           var fileAndSubfiles = [file];
@@ -238,9 +284,9 @@
 
   /// Creates a symlink to the `packages` directory in [dir] if none exists.
   Future _linkSecondaryPackageDir(String dir) {
-    var to = join(dir, 'packages');
-    return exists(to).then((exists) {
-      if (exists) return;
+    return defer(() {
+      var to = join(dir, 'packages');
+      if (entryExists(to)) return;
       return createSymlink(path, to);
     });
   }
diff --git a/utils/pub/error_group.dart b/utils/pub/error_group.dart
index b78ceac..90edfa5 100644
--- a/utils/pub/error_group.dart
+++ b/utils/pub/error_group.dart
@@ -6,6 +6,8 @@
 
 import 'dart:async';
 
+import 'utils.dart';
+
 /// An [ErrorGroup] entangles the errors of multiple [Future]s and [Stream]s
 /// with one another. This allows APIs to expose multiple [Future]s and
 /// [Stream]s that have identical error conditions without forcing API consumers
@@ -179,7 +181,7 @@
     _completer.future.catchError((_) {});
   }
 
-  Future then(onValue(T value), {onError(AsyncError asyncError)}) {
+  Future then(onValue(value), {onError(AsyncError asyncError)}) {
     _hasListeners = true;
     return _completer.future.then(onValue, onError: onError);
   }
@@ -194,7 +196,7 @@
     return _completer.future.whenComplete(action);
   }
 
-  Stream<T> asStream() {
+  Stream asStream() {
     _hasListeners = true;
     return _completer.future.asStream();
   }
@@ -260,7 +262,7 @@
     if (_isDone) return;
     _subscription.cancel();
     // Call these asynchronously to work around issue 7913.
-    new Future.immediate(null).then((_) {
+    defer(() {
       _controller.signalError(e.error, e.stackTrace);
       _controller.close();
     });
diff --git a/utils/pub/git_source.dart b/utils/pub/git_source.dart
index 477cc17..f37db91 100644
--- a/utils/pub/git_source.dart
+++ b/utils/pub/git_source.dart
@@ -42,24 +42,28 @@
             "Please ensure Git is correctly installed.");
       }
 
-      return ensureDir(join(systemCacheRoot, 'cache'));
-    }).then((_) => _ensureRepoCache(id))
-      .then((_) => _revisionCachePath(id))
-      .then((path) {
+      ensureDir(join(systemCacheRoot, 'cache'));
+      return _ensureRepoCache(id);
+    }).then((_) => systemCacheDirectory(id)).then((path) {
       revisionCachePath = path;
-      return exists(revisionCachePath);
-    }).then((exists) {
-      if (exists) return;
+      if (entryExists(revisionCachePath)) return;
       return _clone(_repoCachePath(id), revisionCachePath, mirror: false);
     }).then((_) {
       var ref = _getEffectiveRef(id);
       if (ref == 'HEAD') return;
       return _checkOut(revisionCachePath, ref);
     }).then((_) {
-      return Package.load(id.name, revisionCachePath, systemCache.sources);
+      return new Package.load(id.name, revisionCachePath, systemCache.sources);
     });
   }
 
+  /// Returns the path to the revision-specific cache of [id].
+  Future<String> systemCacheDirectory(PackageId id) {
+    return _revisionAt(id).then((rev) {
+      var revisionCacheName = '${id.name}-$rev';
+      return join(systemCacheRoot, revisionCacheName);
+    });
+  }
   /// Ensures [description] is a Git URL.
   void validateDescription(description, {bool fromLockFile: false}) {
     // A single string is assumed to be a Git URL.
@@ -104,10 +108,9 @@
   /// future that completes once this is finished and throws an exception if it
   /// fails.
   Future _ensureRepoCache(PackageId id) {
-    var path = _repoCachePath(id);
-    return exists(path).then((exists) {
-      if (!exists) return _clone(_getUrl(id), path, mirror: true);
-
+    return defer(() {
+      var path = _repoCachePath(id);
+      if (!entryExists(path)) return _clone(_getUrl(id), path, mirror: true);
       return git.run(["fetch"], workingDir: path).then((result) => null);
     });
   }
@@ -118,14 +121,6 @@
         workingDir: _repoCachePath(id)).then((result) => result[0]);
   }
 
-  /// Returns the path to the revision-specific cache of [id].
-  Future<String> _revisionCachePath(PackageId id) {
-    return _revisionAt(id).then((rev) {
-      var revisionCacheName = '${id.name}-$rev';
-      return join(systemCacheRoot, revisionCacheName);
-    });
-  }
-
   /// Clones the repo at the URI [from] to the path [to] on the local
   /// filesystem.
   ///
@@ -133,9 +128,10 @@
   /// the working tree, but instead makes the repository a local mirror of the
   /// remote repository. See the manpage for `git clone` for more information.
   Future _clone(String from, String to, {bool mirror: false}) {
-    // Git on Windows does not seem to automatically create the destination
-    // directory.
-    return ensureDir(to).then((_) {
+    return defer(() {
+      // Git on Windows does not seem to automatically create the destination
+      // directory.
+      ensureDir(to);
       var args = ["clone", from, to];
       if (mirror) args.insertRange(1, 1, "--mirror");
       return git.run(args);
diff --git a/utils/pub/hosted_source.dart b/utils/pub/hosted_source.dart
index b774bc0..2db9cc8 100644
--- a/utils/pub/hosted_source.dart
+++ b/utils/pub/hosted_source.dart
@@ -28,7 +28,7 @@
   final shouldCache = true;
 
   /// The URL of the default package repository.
-  static final defaultUrl = "http://pub.dartlang.org";
+  static final defaultUrl = "https://pub.dartlang.org";
 
   /// Downloads a list of all versions of a package that are available from the
   /// site.
@@ -77,7 +77,7 @@
           .then((response) => response.stream),
       systemCache.createTempDir()
     ]).then((args) {
-      var stream = streamToInputStream(args[0]);
+      var stream = args[0];
       tempDir = args[1];
       return timeout(extractTarGz(stream, tempDir), HTTP_TIMEOUT,
           'fetching URL "$fullUrl"');
@@ -93,13 +93,15 @@
   /// for each separate repository URL that's used on the system. Each of these
   /// subdirectories then contains a subdirectory for each package installed
   /// from that site.
-  String systemCacheDirectory(PackageId id) {
+  Future<String> systemCacheDirectory(PackageId id) {
     var parsed = _parseDescription(id.description);
     var url = parsed.last.replaceAll(new RegExp(r"^https?://"), "");
     var urlDir = replace(url, new RegExp(r'[<>:"\\/|?*%]'), (match) {
       return '%${match[0].charCodeAt(0)}';
     });
-    return join(systemCacheRoot, urlDir, "${parsed.first}-${id.version}");
+
+    return new Future.immediate(
+        join(systemCacheRoot, urlDir, "${parsed.first}-${id.version}"));
   }
 
   String packageName(description) => _parseDescription(description).first;
diff --git a/utils/pub/http.dart b/utils/pub/http.dart
index e148418..f8cb699 100644
--- a/utils/pub/http.dart
+++ b/utils/pub/http.dart
@@ -11,7 +11,6 @@
 
 // TODO(nweiz): Make this import better.
 import '../../pkg/http/lib/http.dart' as http;
-import 'curl_client.dart';
 import 'io.dart';
 import 'log.dart' as log;
 import 'utils.dart';
@@ -57,12 +56,16 @@
       });
     }).catchError((asyncError) {
       if (asyncError.error is SocketIOException &&
-          asyncError.error.osError != null &&
-          (asyncError.error.osError.errorCode == 8 ||
-           asyncError.error.osError.errorCode == -2 ||
-           asyncError.error.osError.errorCode == -5 ||
-           asyncError.error.osError.errorCode == 11004)) {
-        throw 'Could not resolve URL "${request.url.origin}".';
+          asyncError.error.osError != null) {
+        if (asyncError.error.osError.errorCode == 8 ||
+            asyncError.error.osError.errorCode == -2 ||
+            asyncError.error.osError.errorCode == -5 ||
+            asyncError.error.osError.errorCode == 11004) {
+          throw 'Could not resolve URL "${request.url.origin}".';
+        } else if (asyncError.error.osError.errorCode == -12276) {
+          throw 'Unable to validate SSL certificate for '
+              '"${request.url.origin}".';
+        }
       }
       throw asyncError;
     }), HTTP_TIMEOUT, 'fetching URL "${request.url}"');
@@ -72,8 +75,6 @@
 /// The HTTP client to use for all HTTP requests.
 final httpClient = new PubHttpClient();
 
-final curlClient = new PubHttpClient(new CurlClient());
-
 /// Handles a successful JSON-formatted response from pub.dartlang.org.
 ///
 /// These responses are expected to be of the form `{"success": {"message":
diff --git a/utils/pub/io.dart b/utils/pub/io.dart
index 8243a28..60f6d77 100644
--- a/utils/pub/io.dart
+++ b/utils/pub/io.dart
@@ -12,9 +12,14 @@
 import 'dart:uri';
 
 import '../../pkg/path/lib/path.dart' as path;
+import '../../pkg/http/lib/http.dart' show ByteStream;
+import 'error_group.dart';
+import 'exit_codes.dart' as exit_codes;
 import 'log.dart' as log;
 import 'utils.dart';
 
+export '../../pkg/http/lib/http.dart' show ByteStream;
+
 final NEWLINE_PATTERN = new RegExp("\r\n?|\n\r?");
 
 /// Joins a number of path string parts into a single path. Handles
@@ -49,41 +54,17 @@
 /// Returns the path to [target] from [base].
 String relativeTo(target, base) => path.relative(target, from: base);
 
-/// Asynchronously determines if [path], which can be a [String] file path, a
-/// [File], or a [Directory] exists on the file system. Returns a [Future] that
-/// completes with the result.
-Future<bool> exists(path) {
-  path = _getPath(path);
-  return Future.wait([fileExists(path), dirExists(path)]).then((results) {
-    return results[0] || results[1];
-  });
-}
+/// 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);
 
-/// Asynchronously determines if [file], which can be a [String] file path or a
-/// [File], exists on the file system. Returns a [Future] that completes with
-/// the result.
-Future<bool> fileExists(file) {
-  var path = _getPath(file);
-  return log.ioAsync("Seeing if file $path exists.",
-      new File(path).exists(),
-      (exists) => "File $path ${exists ? 'exists' : 'does not exist'}.");
-}
+/// Determines if [file], which can be a [String] file path or a [File], exists
+/// on the file system.
+bool fileExists(file) => _getFile(file).existsSync();
 
 /// Reads the contents of the text file [file], which can either be a [String]
 /// or a [File].
-Future<String> readTextFile(file) {
-  var path = _getPath(file);
-  return log.ioAsync("Reading text file $path.",
-      new File(path).readAsString(Encoding.UTF_8),
-      (contents) {
-        // Sanity check: don't spew a huge file.
-        if (contents.length < 1024 * 1024) {
-          return "Read $path. Contents:\n$contents";
-        } else {
-          return "Read ${contents.length} characters from $path.";
-        }
-      });
-}
+String readTextFile(file) => _getFile(file).readAsStringSync(Encoding.UTF_8);
 
 /// Reads the contents of the binary file [file], which can either be a [String]
 /// or a [File].
@@ -96,10 +77,10 @@
 }
 
 /// Creates [file] (which can either be a [String] or a [File]), and writes
-/// [contents] to it. Completes when the file is written and closed.
+/// [contents] to it.
 ///
 /// If [dontLogContents] is true, the contents of the file will never be logged.
-Future<File> writeTextFile(file, String contents, {dontLogContents: false}) {
+File writeTextFile(file, String contents, {dontLogContents: false}) {
   var path = _getPath(file);
   file = new File(path);
 
@@ -109,16 +90,13 @@
     log.fine("Contents:\n$contents");
   }
 
-  return file.open(FileMode.WRITE).then((opened) {
-    return opened.writeString(contents).then((ignore) {
-        return opened.close().then((_) {
-          log.fine("Wrote text file $path.");
-          return file;
-        });
-    });
-  });
+  return file..writeAsStringSync(contents);
 }
 
+/// Deletes [file], which can be a [String] or a [File]. Returns a [Future]
+/// that completes when the deletion is done.
+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) {
@@ -133,93 +111,46 @@
   return file;
 }
 
-/// Asynchronously deletes [file], which can be a [String] or a [File]. Returns
-/// a [Future] that completes when the deletion is done.
-Future<File> deleteFile(file) {
-  var path = _getPath(file);
-  return log.ioAsync("delete file $path",
-      new File(path).delete());
-}
-
 /// 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(InputStream stream, path) {
+Future<File> createFileFromStream(Stream<List<int>> stream, path) {
   path = _getPath(path);
 
   log.io("Creating $path from stream.");
 
-  var completer = new Completer<File>();
-  var completed = false;
   var file = new File(path);
-  var outputStream = file.openOutputStream();
-  stream.pipe(outputStream);
-
-  outputStream.onClosed = () {
+  return stream.pipe(wrapOutputStream(file.openOutputStream())).then((_) {
     log.fine("Created $path from stream.");
-    completed = true;
-    completer.complete(file);
-  };
-
-  // TODO(nweiz): remove this when issue 4061 is fixed.
-  var stackTrace;
-  try {
-    throw "";
-  } catch (_, localStackTrace) {
-    stackTrace = localStackTrace;
-  }
-
-  completeError(error) {
-    if (!completed) {
-      completed = true;
-      completer.completeError(error, stackTrace);
-    } else {
-      log.fine("Got error after stream was closed: $error");
-    }
-  }
-
-  stream.onError = completeError;
-  outputStream.onError = completeError;
-
-  return completer.future;
+  });
 }
 
-/// Creates a directory [dir]. Returns a [Future] that completes when the
-/// directory is created.
-Future<Directory> createDir(dir) {
-  dir = _getDirectory(dir);
-  return log.ioAsync("create directory ${dir.path}",
-      dir.create());
-}
+/// Creates a directory [dir].
+Directory createDir(dir) => _getDirectory(dir)..createSync();
 
 /// Ensures that [path] and all its parent directories exist. If they don't
-/// exist, creates them. Returns a [Future] that completes once all the
-/// directories are created.
-Future<Directory> ensureDir(path) {
+/// exist, creates them.
+Directory ensureDir(path) {
   path = _getPath(path);
+
   log.fine("Ensuring directory $path exists.");
-  if (path == '.') return new Future.immediate(new Directory('.'));
+  var dir = new Directory(path);
+  if (path == '.' || dirExists(path)) return dir;
 
-  return dirExists(path).then((exists) {
-    if (exists) {
-      log.fine("Directory $path already exists.");
-      return new Directory(path);
+  ensureDir(dirname(path));
+
+  try {
+    createDir(dir);
+  } on DirectoryIOException catch (ex) {
+    // Error 17 means the directory already exists (or 183 on Windows).
+    if (ex.osError.errorCode == 17 || ex.osError.errorCode == 183) {
+      log.fine("Got 'already exists' error when creating directory.");
+    } else {
+      throw ex;
     }
+  }
 
-    return ensureDir(dirname(path)).then((_) {
-      return createDir(path).catchError((asyncError) {
-        if (asyncError.error is! DirectoryIOException) throw asyncError;
-        // Error 17 means the directory already exists (or 183 on Windows).
-        if (asyncError.error.osError.errorCode == 17 ||
-            asyncError.error.osError.errorCode == 183) {
-          log.fine("Got 'already exists' error when creating directory.");
-          return _getDirectory(path);
-        }
-
-        throw asyncError;
-      });
-    });
-  });
+  return dir;
 }
 
 /// Creates a temp directory whose name will be based on [dir] with a unique
@@ -259,6 +190,7 @@
     if (listedDirectories.contains(resolvedPath)) {
       return new Future.immediate([]);
     }
+
     listedDirectories = new Set<String>.from(listedDirectories);
     listedDirectories.add(resolvedPath);
 
@@ -289,7 +221,6 @@
       if (!includeHiddenFiles && basename(file).startsWith('.')) return;
       file = join(dir, 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.
@@ -297,6 +228,7 @@
         children.add(doList(new Directory(file), listedDirectories));
       }
     };
+
     lister.onFile = (file) {
       if (!includeHiddenFiles && basename(file).startsWith('.')) return;
       contents.add(join(dir, basename(file)));
@@ -313,23 +245,16 @@
   return doList(_getDirectory(dir), new Set<String>());
 }
 
-/// Asynchronously determines if [dir], which can be a [String] directory path
-/// or a [Directory], exists on the file system. Returns a [Future] that
-/// completes with the result.
-Future<bool> dirExists(dir) {
-  dir = _getDirectory(dir);
-  return log.ioAsync("Seeing if directory ${dir.path} exists.",
-      dir.exists(),
-      (exists) => "Directory ${dir.path} "
-                  "${exists ? 'exists' : 'does not exist'}.");
-}
+/// Determines if [dir], which can be a [String] directory path or a
+/// [Directory], exists on the file system.
+bool dirExists(dir) => _getDirectory(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) {
-  return dirExists(dir).then((exists) {
-    if (exists) {
+  return defer(() {
+    if (dirExists(dir)) {
       // Delete it first.
       return deleteDir(dir).then((_) => createDir(dir));
     } else {
@@ -384,6 +309,8 @@
 /// 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]).
+///
+/// Note that on Windows, only directories may be symlinked to.
 Future<File> createSymlink(from, to) {
   from = _getPath(from);
   to = _getPath(to);
@@ -416,11 +343,11 @@
 /// appropriate and then does nothing.
 Future<File> createPackageSymlink(String name, from, to,
     {bool isSelfLink: false}) {
-  // See if the package has a "lib" directory.
-  from = join(from, 'lib');
-  return dirExists(from).then((exists) {
+  return defer(() {
+    // See if the package has a "lib" directory.
+    from = join(from, 'lib');
     log.fine("Creating ${isSelfLink ? "self" : ""}link for package '$name'.");
-    if (exists) return createSymlink(from, to);
+    if (dirExists(from)) return createSymlink(from, to);
 
     // It's OK for the self link (i.e. the root package) to not have a lib
     // directory since it may just be a leaf application that only has
@@ -430,7 +357,7 @@
                   'you will not be able to import any libraries from it.');
     }
 
-    return to;
+    return _getFile(to);
   });
 }
 
@@ -457,8 +384,33 @@
   return path.normalize(join(utilDir, 'pub', target));
 }
 
-/// A StringInputStream reading from stdin.
-final _stringStdin = new StringInputStream(stdin);
+// TODO(nweiz): add a ByteSink wrapper to make writing strings to stdout/stderr
+// nicer.
+
+/// A sink that writes to standard output. Errors piped to this stream will be
+/// surfaced to the top-level error handler.
+final StreamSink<List<int>> stdoutSink = _wrapStdio(stdout, "stdout");
+
+/// A sink that writes to standard error. Errors piped to this stream will be
+/// surfaced to the top-level error handler.
+final StreamSink<List<int>> stderrSink = _wrapStdio(stderr, "stderr");
+
+/// Wrap the standard output or error [stream] in a [StreamSink]. Any errors are
+/// logged, and then the program is terminated. [name] is used for debugging.
+StreamSink<List<int>> _wrapStdio(OutputStream stream, String name) {
+  var pair = consumerToSink(wrapOutputStream(stream));
+  pair.last.catchError((e) {
+    // This log may or may not work, depending on how the stream failed. Not
+    // much we can do about that.
+    log.error("Error writing to $name: $e");
+    exit(exit_codes.IO);
+  });
+  return pair.first;
+}
+
+/// A line-by-line stream of standard input.
+final Stream<String> stdinLines =
+    streamToLines(wrapInputStream(stdin).toStringStream());
 
 /// Displays a message and reads a yes/no confirmation from the user. Returns
 /// a [Future] that completes to `true` if the user confirms or `false` if they
@@ -468,143 +420,28 @@
 /// should just be a fragment like, "Are you sure you want to proceed".
 Future<bool> confirm(String message) {
   log.fine('Showing confirm message: $message');
-  stdout.writeString("$message (y/n)? ");
-  return readLine().then((line) => new RegExp(r"^[yY]").hasMatch(line));
-}
-
-/// Returns a single line read from a [StringInputStream]. By default, reads
-/// from stdin.
-///
-/// A [StringInputStream] passed to this should have no callbacks registered.
-Future<String> readLine([StringInputStream stream]) {
-  if (stream == null) stream = _stringStdin;
-  if (stream.closed) return new Future.immediate('');
-  void removeCallbacks() {
-    stream.onClosed = null;
-    stream.onLine = null;
-    stream.onError = null;
-  }
-
-  // TODO(nweiz): remove this when issue 4061 is fixed.
-  var stackTrace;
-  try {
-    throw "";
-  } catch (_, localStackTrace) {
-    stackTrace = localStackTrace;
-  }
-
-  var completer = new Completer();
-  stream.onClosed = () {
-    removeCallbacks();
-    completer.complete('');
-  };
-
-  stream.onLine = () {
-    removeCallbacks();
-    var line = stream.readLine();
-    log.io('Read line: $line');
-    completer.complete(line);
-  };
-
-  stream.onError = (e) {
-    removeCallbacks();
-    completer.completeError(e, stackTrace);
-  };
-
-  return completer.future;
-}
-
-/// Takes all input from [source] and writes it to [sink].
-///
-/// Returns a future that completes when [source] is closed.
-Future pipeInputToInput(InputStream source, ListInputStream sink) {
-  var completer = new Completer();
-  source.onClosed = () {
-    sink.markEndOfStream();
-    completer.complete(null);
-  };
-  source.onData = () {
-    // Even if the sink is closed and we aren't going to do anything with more
-    // data, we still need to drain it from source to work around issue 7218.
-    var data = source.read();
-    try {
-      if (!sink.closed) sink.write(data);
-    } on StreamException catch (e, stackTrace) {
-      // Ignore an exception to work around issue 4222.
-      log.io("Writing to an unclosed ListInputStream caused exception $e\n"
-          "$stackTrace");
-    }
-  };
-  // TODO(nweiz): propagate this error to the sink. See issue 3657.
-  source.onError = (e) { throw e; };
-  return completer.future;
-}
-
-/// Buffers all input from an InputStream and returns it as a future.
-Future<List<int>> consumeInputStream(InputStream stream) {
-  if (stream.closed) return new Future.immediate(<int>[]);
-
-  // TODO(nweiz): remove this when issue 4061 is fixed.
-  var stackTrace;
-  try {
-    throw "";
-  } catch (_, localStackTrace) {
-    stackTrace = localStackTrace;
-  }
-
-  var completer = new Completer<List<int>>();
-  var buffer = <int>[];
-  stream.onClosed = () => completer.complete(buffer);
-  stream.onData = () => buffer.addAll(stream.read());
-  stream.onError = (e) => completer.completeError(e, stackTrace);
-  return completer.future;
-}
-
-/// Buffers all input from a StringInputStream and returns it as a future.
-Future<String> consumeStringInputStream(StringInputStream stream) {
-  if (stream.closed) return new Future.immediate('');
-
-  // TODO(nweiz): remove this when issue 4061 is fixed.
-  var stackTrace;
-  try {
-    throw "";
-  } catch (_, localStackTrace) {
-    stackTrace = localStackTrace;
-  }
-
-  var completer = new Completer<String>();
-  var buffer = new StringBuffer();
-  stream.onClosed = () => completer.complete(buffer.toString());
-  stream.onData = () => buffer.add(stream.read());
-  stream.onError = (e) => completer.completeError(e, stackTrace);
-  return completer.future;
+  stdoutSink.add("$message (y/n)? ".charCodes);
+  return streamFirst(stdinLines)
+      .then((line) => new RegExp(r"^[yY]").hasMatch(line));
 }
 
 /// Wraps [stream] in a single-subscription [Stream] that emits the same data.
-Stream<List<int>> wrapInputStream(InputStream stream) {
+ByteStream wrapInputStream(InputStream stream) {
   var controller = new StreamController();
   if (stream.closed) {
     controller.close();
-    return controller.stream;
+    return new ByteStream(controller.stream);
   }
 
   stream.onClosed = controller.close;
   stream.onData = () => controller.add(stream.read());
   stream.onError = (e) => controller.signalError(new AsyncError(e));
-  return controller.stream;
-}
-
-// TODO(nweiz): remove this ASAP (issue 7807).
-/// Wraps [stream] in an [InputStream].
-InputStream streamToInputStream(Stream<List<int>> stream) {
-  var inputStream = new ListInputStream();
-  stream.listen((chunk) => inputStream.write(chunk),
-      onDone: inputStream.markEndOfStream);
-  return inputStream;
+  return new ByteStream(controller.stream);
 }
 
 /// Wraps [stream] in a [StreamConsumer] so that [Stream]s can by piped into it
-/// using [Stream.pipe].
+/// using [Stream.pipe]. Errors piped to the returned [StreamConsumer] will be
+/// forwarded to the [Future] returned by [Stream.pipe].
 StreamConsumer<List<int>, dynamic> wrapOutputStream(OutputStream stream) =>
   new _OutputStreamConsumer(stream);
 
@@ -632,6 +469,9 @@
         if (!completed) completer.completeError(e, stack);
         completed = true;
       }
+    }, onError: (e) {
+      if (!completed) completer.completeError(e.error, e.stackTrace);
+      completed = true;
     }, onDone: () => _outputStream.close());
 
     _outputStream.onError = (e) {
@@ -648,6 +488,43 @@
   }
 }
 
+/// Returns a [StreamSink] that pipes all data to [consumer] and a [Future] that
+/// will succeed when [StreamSink] is closed or fail with any errors that occur
+/// while writing.
+Pair<StreamSink, Future> consumerToSink(StreamConsumer consumer) {
+  var controller = new StreamController();
+  var done = controller.stream.pipe(consumer);
+  return new Pair<StreamSink, Future>(controller.sink, done);
+}
+
+// TODO(nweiz): remove this when issue 7786 is fixed.
+/// Pipes all data and errors from [stream] into [sink]. When [stream] is done,
+/// the returned [Future] is completed and [sink] is closed if [closeSink] is
+/// true.
+///
+/// When an error occurs on [stream], that error is passed to [sink]. If
+/// [unsubscribeOnError] is true, [Future] will be completed successfully and no
+/// more data or errors will be piped from [stream] to [sink]. If
+/// [unsubscribeOnError] and [closeSink] are both true, [sink] will then be
+/// closed.
+Future store(Stream stream, StreamSink sink,
+    {bool unsubscribeOnError: true, closeSink: true}) {
+  var completer = new Completer();
+  stream.listen(sink.add,
+      onError: (e) {
+        sink.signalError(e);
+        if (unsubscribeOnError) {
+          completer.complete();
+          if (closeSink) sink.close();
+        }
+      },
+      onDone: () {
+        if (closeSink) sink.close();
+        completer.complete();
+      }, unsubscribeOnError: unsubscribeOnError);
+  return completer.future;
+}
+
 /// Spawns and runs the process located at [executable], passing in [args].
 /// Returns a [Future] that will complete with the results of the process after
 /// it has ended.
@@ -681,41 +558,92 @@
 /// The spawned process will inherit its parent's environment variables. If
 /// [environment] is provided, that will be used to augment (not replace) the
 /// the inherited variables.
-Future<Process> startProcess(String executable, List<String> args,
+Future<PubProcess> startProcess(String executable, List<String> args,
     {workingDir, Map<String, String> environment}) =>
   _doProcess(Process.start, executable, args, workingDir, environment)
-    .then((process) => new _WrappedProcess(process));
+      .then((process) => new PubProcess(process));
 
-/// A wrapper around [Process] that buffers the stdout and stderr to avoid
-/// running into issue 7218.
-class _WrappedProcess implements Process {
+/// A wrapper around [Process] that exposes `dart:async`-style APIs.
+class PubProcess {
+  /// The underlying `dart:io` [Process].
   final Process _process;
-  final InputStream stderr;
-  final InputStream stdout;
 
-  OutputStream get stdin => _process.stdin;
+  /// The mutable field for [stdin].
+  StreamSink<List<int>> _stdin;
 
-  void set onExit(void callback(int exitCode)) {
-    _process.onExit = callback;
+  /// The mutable field for [stdinClosed].
+  Future _stdinClosed;
+
+  /// The mutable field for [stdout].
+  ByteStream _stdout;
+
+  /// The mutable field for [stderr].
+  ByteStream _stderr;
+
+  /// The mutable field for [exitCode].
+  Future<int> _exitCode;
+
+  /// The sink used for passing data to the process's standard input stream.
+  /// Errors on this stream are surfaced through [stdinClosed], [stdout],
+  /// [stderr], and [exitCode], which are all members of an [ErrorGroup].
+  StreamSink<List<int>> get stdin => _stdin;
+
+  // TODO(nweiz): write some more sophisticated Future machinery so that this
+  // doesn't surface errors from the other streams/futures, but still passes its
+  // unhandled errors to them. Right now it's impossible to recover from a stdin
+  // error and continue interacting with the process.
+  /// A [Future] that completes when [stdin] is closed, either by the user or by
+  /// the process itself.
+  ///
+  /// This is in an [ErrorGroup] with [stdout], [stderr], and [exitCode], so any
+  /// error in process will be passed to it, but won't reach the top-level error
+  /// handler unless nothing has handled it.
+  Future get stdinClosed => _stdinClosed;
+
+  /// The process's standard output stream.
+  ///
+  /// This is in an [ErrorGroup] with [stdinClosed], [stderr], and [exitCode],
+  /// so any error in process will be passed to it, but won't reach the
+  /// top-level error handler unless nothing has handled it.
+  ByteStream get stdout => _stdout;
+
+  /// The process's standard error stream.
+  ///
+  /// This is in an [ErrorGroup] with [stdinClosed], [stdout], and [exitCode],
+  /// so any error in process will be passed to it, but won't reach the
+  /// top-level error handler unless nothing has handled it.
+  ByteStream get stderr => _stderr;
+
+  /// A [Future] that will complete to the process's exit code once the process
+  /// has finished running.
+  ///
+  /// This is in an [ErrorGroup] with [stdinClosed], [stdout], and [stderr], so
+  /// any error in process will be passed to it, but won't reach the top-level
+  /// error handler unless nothing has handled it.
+  Future<int> get exitCode => _exitCode;
+
+  /// Creates a new [PubProcess] wrapping [process].
+  PubProcess(Process process)
+    : _process = process {
+    var errorGroup = new ErrorGroup();
+
+    var pair = consumerToSink(wrapOutputStream(process.stdin));
+    _stdin = pair.first;
+    _stdinClosed = errorGroup.registerFuture(pair.last);
+
+    _stdout = new ByteStream(
+        errorGroup.registerStream(wrapInputStream(process.stdout)));
+    _stderr = new ByteStream(
+        errorGroup.registerStream(wrapInputStream(process.stderr)));
+
+    var exitCodeCompleter = new Completer();
+    _exitCode = errorGroup.registerFuture(exitCodeCompleter.future);
+    _process.onExit = (code) => exitCodeCompleter.complete(code);
   }
 
-  _WrappedProcess(Process process)
-    : _process = process,
-      stderr = _wrapInputStream(process.stderr),
-      stdout = _wrapInputStream(process.stdout);
-
+  /// Sends [signal] to the underlying process.
   bool kill([ProcessSignal signal = ProcessSignal.SIGTERM]) =>
     _process.kill(signal);
-
-  /// Wrap an InputStream in a ListInputStream. This eagerly drains the [source]
-  /// input stream. This is useful for spawned processes which will not exit
-  /// until their output streams have been drained. TODO(rnystrom): We should
-  /// use this logic anywhere we spawn a process.
-  static InputStream _wrapInputStream(InputStream source) {
-    var sink = new ListInputStream();
-    pipeInputToInput(source, sink);
-    return sink;
-  }
 }
 
 /// Calls [fn] with appropriately modified arguments. [fn] should have the same
@@ -792,7 +720,7 @@
 
 /// 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(InputStream stream, destination) {
+Future<bool> extractTarGz(Stream<List<int>> stream, destination) {
   destination = _getPath(destination);
 
   log.fine("Extracting .tar.gz stream to $destination.");
@@ -801,27 +729,29 @@
     return _extractTarGzWindows(stream, destination);
   }
 
-  var completer = new Completer<int>();
-  var processFuture = startProcess("tar",
-      ["--extract", "--gunzip", "--directory", destination]);
-  processFuture.then((process) {
-    process.onExit = (exitCode) => completer.complete(exitCode);
-    stream.pipe(process.stdin);
-    process.stdout.pipe(stdout, close: false);
-    process.stderr.pipe(stderr, close: false);
-  }).catchError((e) {
-    completer.completeError(e.error, e.stackTrace);
-  });
-
-  return completer.future.then((exitCode) {
+  return startProcess("tar",
+      ["--extract", "--gunzip", "--directory", destination]).then((process) {
+    // Ignore errors on process.std{out,err}. They'll be passed to
+    // process.exitCode, and we don't want them being top-levelled by
+    // std{out,err}Sink.
+    store(process.stdout.handleError((_) {}), stdoutSink, closeSink: false);
+    store(process.stderr.handleError((_) {}), stderrSink, closeSink: false);
+    return Future.wait([
+      store(stream, process.stdin),
+      process.exitCode
+    ]);
+  }).then((results) {
+    var exitCode = results[1];
+    if (exitCode != 0) {
+      throw "Failed to extract .tar.gz stream to $destination (exit code "
+        "$exitCode).";
+    }
     log.fine("Extracted .tar.gz stream to $destination. Exit code $exitCode.");
-    // TODO(rnystrom): Does anything check this result value? If not, it should
-    // throw on a bad exit code.
-    return exitCode == 0;
   });
 }
 
-Future<bool> _extractTarGzWindows(InputStream stream, String destination) {
+Future<bool> _extractTarGzWindows(Stream<List<int>> stream,
+    String destination) {
   // TODO(rnystrom): In the repo's history, there is an older implementation of
   // this that does everything in memory by piping streams directly together
   // instead of writing out temp files. The code is simpler, but unfortunately,
@@ -884,8 +814,8 @@
 /// Create a .tar.gz archive from a list of entries. Each entry can be a
 /// [String], [Directory], or [File] object. The root of the archive is
 /// considered to be [baseDir], which defaults to the current working directory.
-/// Returns an [InputStream] that will emit the contents of the archive.
-InputStream createTarGz(List contents, {baseDir}) {
+/// Returns a [ByteStream] that will emit the contents of the archive.
+ByteStream createTarGz(List contents, {baseDir}) {
   var buffer = new StringBuffer();
   buffer.add('Creating .tag.gz stream containing:\n');
   contents.forEach((file) => buffer.add('$file\n'));
@@ -893,7 +823,7 @@
 
   // TODO(nweiz): Propagate errors to the returned stream (including non-zero
   // exit codes). See issue 3657.
-  var stream = new ListInputStream();
+  var controller = new StreamController<List<int>>();
 
   if (baseDir == null) baseDir = path.current;
   baseDir = getFullPath(baseDir);
@@ -912,15 +842,14 @@
     // 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.
     startProcess("tar", args).then((process) {
-      pipeInputToInput(process.stdout, stream);
-
-      // Drain and discard 7zip's stderr. 7zip writes its normal output to
-      // stderr. We don't want to show that since it's meaningless.
-      // TODO(rnystrom): Should log this and display it if an actual error
-      // occurs.
-      consumeInputStream(process.stderr);
+      store(process.stdout, controller);
+    }).catchError((e) {
+      // We don't have to worry about double-signaling here, since the store()
+      // above will only be reached if startProcess succeeds.
+      controller.signalError(e.error, e.stackTrace);
+      controller.close();
     });
-    return stream;
+    return new ByteStream(controller.stream);
   }
 
   withTempDir((tempDir) {
@@ -944,15 +873,20 @@
       args = ["a", "unused", "-tgzip", "-so", tarFile];
       return startProcess(command, args);
     }).then((process) {
-      // Drain and discard 7zip's stderr. 7zip writes its normal output to
-      // stderr. We don't want to show that since it's meaningless.
-      // TODO(rnystrom): Should log this and display it if an actual error
+      // Ignore 7zip's stderr. 7zip writes its normal output to stderr. We don't
+      // want to show that since it's meaningless.
+      //
+      // TODO(rnystrom): Should log the stderr and display it if an actual error
       // occurs.
-      consumeInputStream(process.stderr);
-      return pipeInputToInput(process.stdout, stream);
+      return store(process.stdout, controller);
     });
+  }).catchError((e) {
+    // We don't have to worry about double-signaling here, since the store()
+    // above will only be reached if everything succeeds.
+    controller.signalError(e.error, e.stackTrace);
+    controller.close();
   });
-  return stream;
+  return new ByteStream(controller.stream);
 }
 
 /// Exception thrown when an operation times out.
@@ -975,6 +909,14 @@
   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.
diff --git a/utils/pub/log.dart b/utils/pub/log.dart
index ee1ad1e..43499ef 100644
--- a/utils/pub/log.dart
+++ b/utils/pub/log.dart
@@ -6,7 +6,6 @@
 library log;
 
 import 'dart:async';
-import 'dart:io';
 import 'io.dart';
 
 typedef LogFn(Entry entry);
@@ -154,11 +153,11 @@
 void dumpTranscript() {
   if (_transcript == null) return;
 
-  stderr.writeString('---- Log transcript ----\n');
+  stderrSink.add('---- Log transcript ----\n'.charCodes);
   for (var entry in _transcript) {
     _logToStderrWithLabel(entry);
   }
-  stderr.writeString('---- End log transcript ----\n');
+  stderrSink.add('---- End log transcript ----\n'.charCodes);
 }
 
 /// Sets the verbosity to "normal", which shows errors, warnings, and messages.
@@ -191,38 +190,38 @@
 
 /// Log function that prints the message to stdout.
 void _logToStdout(Entry entry) {
-  _logToStream(stdout, entry, showLabel: false);
+  _logToStream(stdoutSink, entry, showLabel: false);
 }
 
 /// Log function that prints the message to stdout with the level name.
 void _logToStdoutWithLabel(Entry entry) {
-  _logToStream(stdout, entry, showLabel: true);
+  _logToStream(stdoutSink, entry, showLabel: true);
 }
 
 /// Log function that prints the message to stderr.
 void _logToStderr(Entry entry) {
-  _logToStream(stderr, entry, showLabel: false);
+  _logToStream(stderrSink, entry, showLabel: false);
 }
 
 /// Log function that prints the message to stderr with the level name.
 void _logToStderrWithLabel(Entry entry) {
-  _logToStream(stderr, entry, showLabel: true);
+  _logToStream(stderrSink, entry, showLabel: true);
 }
 
-void _logToStream(OutputStream stream, Entry entry, {bool showLabel}) {
+void _logToStream(Sink<List<int>> sink, Entry entry, {bool showLabel}) {
   bool firstLine = true;
   for (var line in entry.lines) {
     if (showLabel) {
       if (firstLine) {
-        stream.writeString(entry.level.name);
-        stream.writeString(': ');
+        sink.add(entry.level.name.charCodes);
+        sink.add(': '.charCodes);
       } else {
-        stream.writeString('    | ');
+        sink.add('    | '.charCodes);
       }
     }
 
-    stream.writeString(line);
-    stream.writeString('\n');
+    sink.add(line.charCodes);
+    sink.add('\n'.charCodes);
 
     firstLine = false;
   }
diff --git a/utils/pub/oauth2.dart b/utils/pub/oauth2.dart
index 21565a7..9711452 100644
--- a/utils/pub/oauth2.dart
+++ b/utils/pub/oauth2.dart
@@ -51,12 +51,12 @@
 Credentials _credentials;
 
 /// Delete the cached credentials, if they exist.
-Future clearCredentials(SystemCache cache) {
+void clearCredentials(SystemCache cache) {
   _credentials = null;
   var credentialsFile = _credentialsFile(cache);
-  return fileExists(credentialsFile).then((exists) {
-    if (exists) return deleteFile(credentialsFile);
-  });
+  if (!fileExists(credentialsFile)) return;
+
+  deleteFile(credentialsFile);
 }
 
 /// Asynchronously passes an OAuth2 [Client] to [fn], and closes the client when
@@ -71,7 +71,7 @@
     return fn(client).whenComplete(() {
       client.close();
       // Be sure to save the credentials even when an error happens.
-      return _saveCredentials(cache, client.credentials);
+      _saveCredentials(cache, client.credentials);
     });
   }).catchError((asyncError) {
     if (asyncError.error is ExpirationException) {
@@ -84,7 +84,8 @@
         message = "$message (${asyncError.error.description})";
       }
       log.error("$message.");
-      return clearCredentials(cache).then((_) => withClient(cache, fn));
+      clearCredentials(cache);
+      return withClient(cache, fn);
     } else {
       throw asyncError;
     }
@@ -94,58 +95,52 @@
 /// Gets a new OAuth2 client. If saved credentials are available, those are
 /// used; otherwise, the user is prompted to authorize the pub client.
 Future<Client> _getClient(SystemCache cache) {
-  return _loadCredentials(cache).then((credentials) {
+  return defer(() {
+    var credentials = _loadCredentials(cache);
     if (credentials == null) return _authorize();
-    return new Client(_identifier, _secret, credentials,
-        httpClient: curlClient);
-  }).then((client) {
-    return _saveCredentials(cache, client.credentials).then((_) => client);
+
+    var client = new Client(_identifier, _secret, credentials,
+        httpClient: httpClient);
+    _saveCredentials(cache, client.credentials);
+    return client;
   });
 }
 
 /// Loads the user's OAuth2 credentials from the in-memory cache or the
 /// filesystem if possible. If the credentials can't be loaded for any reason,
 /// the returned [Future] will complete to null.
-Future<Credentials> _loadCredentials(SystemCache cache) {
+Credentials _loadCredentials(SystemCache cache) {
   log.fine('Loading OAuth2 credentials.');
 
-  if (_credentials != null) {
-    log.fine('Using already-loaded credentials.');
-    return new Future.immediate(_credentials);
-  }
+  try {
+    if (_credentials != null) return _credentials;
 
-  var path = _credentialsFile(cache);
-  return fileExists(path).then((credentialsExist) {
-    if (!credentialsExist) {
-      log.fine('No credentials found at $path.');
-      return;
+    var path = _credentialsFile(cache);
+    if (!fileExists(path)) return;
+
+    var credentials = new Credentials.fromJson(readTextFile(path));
+    if (credentials.isExpired && !credentials.canRefresh) {
+      log.error("Pub's authorization to upload packages has expired and "
+          "can't be automatically refreshed.");
+      return null; // null means re-authorize.
     }
 
-    return readTextFile(_credentialsFile(cache)).then((credentialsJson) {
-      var credentials = new Credentials.fromJson(credentialsJson);
-      if (credentials.isExpired && !credentials.canRefresh) {
-        log.error("Pub's authorization to upload packages has expired and "
-            "can't be automatically refreshed.");
-        return null; // null means re-authorize
-      }
-
-      return credentials;
-    });
-  }).catchError((e) {
+    return credentials;
+  } catch (e) {
     log.error('Warning: could not load the saved OAuth2 credentials: $e\n'
         'Obtaining new credentials...');
-    return null; // null means re-authorize
-  });
+    return null; // null means re-authorize.
+  }
 }
 
 /// Save the user's OAuth2 credentials to the in-memory cache and the
 /// filesystem.
-Future _saveCredentials(SystemCache cache, Credentials credentials) {
+void _saveCredentials(SystemCache cache, Credentials credentials) {
   log.fine('Saving OAuth2 credentials.');
   _credentials = credentials;
   var path = _credentialsFile(cache);
-  return ensureDir(dirname(path)).then((_) =>
-      writeTextFile(path, credentials.toJson(), dontLogContents: true));
+  ensureDir(dirname(path));
+  writeTextFile(path, credentials.toJson(), dontLogContents: true);
 }
 
 /// The path to the file in which the user's OAuth2 credentials are stored.
@@ -168,7 +163,7 @@
       _secret,
       _authorizationEndpoint,
       tokenEndpoint,
-      httpClient: curlClient);
+      httpClient: httpClient);
 
   // Spin up a one-shot HTTP server to receive the authorization code from the
   // Google OAuth2 server via redirect. This server will close itself as soon as
@@ -177,7 +172,7 @@
   var server = new HttpServer();
   server.addRequestHandler((request) => request.path == "/",
       (request, response) {
-    chainToCompleter(new Future.immediate(null).then((_) {
+    chainToCompleter(defer(() {
       log.message('Authorization received, processing...');
       var queryString = request.queryString;
       if (queryString == null) queryString = '';
diff --git a/utils/pub/package.dart b/utils/pub/package.dart
index 15fcb97..5485b65 100644
--- a/utils/pub/package.dart
+++ b/utils/pub/package.dart
@@ -15,31 +15,6 @@
 
 /// A named, versioned, unit of code and resource reuse.
 class Package {
-  /// Loads the package whose root directory is [packageDir]. [name] is the
-  /// expected name of that package (e.g. the name given in the dependency), or
-  /// null if the package being loaded is the entrypoint package.
-  static Future<Package> load(String name, String packageDir,
-      SourceRegistry sources) {
-    var pubspecPath = join(packageDir, 'pubspec.yaml');
-
-    return fileExists(pubspecPath).then((exists) {
-      if (!exists) throw new PubspecNotFoundException(name);
-      return readTextFile(pubspecPath);
-    }).then((contents) {
-      try {
-        var pubspec = new Pubspec.parse(contents, sources);
-
-        if (pubspec.name == null) throw new PubspecHasNoNameException(name);
-        if (name != null && pubspec.name != name) {
-          throw new PubspecNameMismatchException(name, pubspec.name);
-        }
-        return new Package._(packageDir, pubspec);
-      } on FormatException catch (ex) {
-        throw 'Could not parse $pubspecPath:\n${ex.message}';
-      }
-    });
-  }
-
   /// The path to the directory containing the package.
   final String dir;
 
@@ -58,7 +33,7 @@
 
   /// The ids of the packages that this package depends on. This is what is
   /// specified in the pubspec when this package depends on another.
-  Collection<PackageRef> get dependencies => pubspec.dependencies;
+  List<PackageRef> get dependencies => pubspec.dependencies;
 
   /// Returns the path to the README file at the root of the entrypoint, or null
   /// if no README file is found. If multiple READMEs are found, this uses the
@@ -80,6 +55,13 @@
     });
   }
 
+  /// Loads the package whose root directory is [packageDir]. [name] is the
+  /// expected name of that package (e.g. the name given in the dependency), or
+  /// `null` if the package being loaded is the entrypoint package.
+  Package.load(String name, String packageDir, SourceRegistry sources)
+      : dir = packageDir,
+        pubspec = new Pubspec.load(name, packageDir, sources);
+
   /// Constructs a package with the given pubspec. The package will have no
   /// directory associated with it.
   Package.inMemory(this.pubspec)
@@ -124,6 +106,10 @@
 
   int get hashCode => name.hashCode ^ source.hashCode ^ version.hashCode;
 
+  /// Gets the directory where this package is or would be found in the
+  /// [SystemCache].
+  Future<String> get systemCacheDirectory => source.systemCacheDirectory(this);
+
   bool operator ==(other) {
     if (other is! PackageId) return false;
     // TODO(rnystrom): We're assuming here the name/version/source tuple is
diff --git a/utils/pub/pub.dart b/utils/pub/pub.dart
index 8a21ecc..db628d0 100644
--- a/utils/pub/pub.dart
+++ b/utils/pub/pub.dart
@@ -109,6 +109,8 @@
       break;
   }
 
+  SecureSocket.initialize(database: relativeToPub('resource/certs'));
+
   var cacheDir;
   if (Platform.environment.containsKey('PUB_CACHE')) {
     cacheDir = Platform.environment['PUB_CACHE'];
@@ -233,43 +235,34 @@
       exit(_chooseExitCode(error));
     }
 
-    var future = new Future.immediate(null);
-    if (requiresEntrypoint) {
-      // TODO(rnystrom): Will eventually need better logic to walk up
-      // subdirectories until we hit one that looks package-like. For now, just
-      // assume the cwd is it.
-      future = Entrypoint.load(path.current, cache);
-    }
-
-    future = future.then((entrypoint) {
-      this.entrypoint = entrypoint;
-      try {
-        var commandFuture = onRun();
-        if (commandFuture == null) return true;
-
-        return commandFuture;
-      } catch (error, trace) {
-        handleError(error, trace);
+    defer(() {
+      if (requiresEntrypoint) {
+        // TODO(rnystrom): Will eventually need better logic to walk up
+        // subdirectories until we hit one that looks package-like. For now,
+        // just assume the cwd is it.
+        entrypoint = new Entrypoint(path.current, cache);
       }
-    });
 
-    future
-      .then((_) => cache_.deleteTempDir())
-      .catchError((asyncError) {
-        var e = asyncError.error;
-        if (e is PubspecNotFoundException && e.name == null) {
-          e = 'Could not find a file named "pubspec.yaml" in the directory '
-            '${path.current}.';
-        } else if (e is PubspecHasNoNameException && e.name == null) {
-          e = 'pubspec.yaml is missing the required "name" field (e.g. "name: '
-            '${basename(path.current)}").';
-        }
+      var commandFuture = onRun();
+      if (commandFuture == null) return true;
 
-        handleError(e, asyncError.stackTrace);
-      })
+      return commandFuture;
+    }).whenComplete(() => cache_.deleteTempDir()).catchError((asyncError) {
+      var e = asyncError.error;
+      if (e is PubspecNotFoundException && e.name == null) {
+        e = 'Could not find a file named "pubspec.yaml" in the directory '
+          '${path.current}.';
+      } else if (e is PubspecHasNoNameException && e.name == null) {
+        e = 'pubspec.yaml is missing the required "name" field (e.g. "name: '
+          '${basename(path.current)}").';
+      }
+
+      handleError(e, asyncError.stackTrace);
+    }).then((_) {
       // Explicitly exit on success to ensure that any dangling dart:io handles
       // don't cause the process to never terminate.
-      .then((_) => exit(0));
+      exit(0);
+    });
   }
 
   /// Override this to perform the specific command. Return a future that
diff --git a/utils/pub/pubspec.dart b/utils/pub/pubspec.dart
index 11b840e..f7c3579 100644
--- a/utils/pub/pubspec.dart
+++ b/utils/pub/pubspec.dart
@@ -4,12 +4,15 @@
 
 library pubspec;
 
+import '../../pkg/yaml/lib/yaml.dart';
+import '../../pkg/path/lib/path.dart' as path;
+
+import 'io.dart';
 import 'package.dart';
 import 'source.dart';
 import 'source_registry.dart';
 import 'utils.dart';
 import 'version.dart';
-import '../../pkg/yaml/lib/yaml.dart';
 
 /// The parsed and validated contents of a pubspec file.
 class Pubspec {
@@ -29,6 +32,28 @@
   /// are derived.
   final Map<String, Object> fields;
 
+  /// Loads the pubspec for a package [name] located in [packageDir].
+  factory Pubspec.load(String name, String packageDir, SourceRegistry sources) {
+    var pubspecPath = path.join(packageDir, 'pubspec.yaml');
+    if (!fileExists(pubspecPath)) throw new PubspecNotFoundException(name);
+
+    try {
+      var pubspec = new Pubspec.parse(readTextFile(pubspecPath), sources);
+
+      if (pubspec.name == null) {
+        throw new PubspecHasNoNameException(name);
+      }
+
+      if (name != null && pubspec.name != name) {
+        throw new PubspecNameMismatchException(name, pubspec.name);
+      }
+
+      return pubspec;
+    } on FormatException catch (ex) {
+      throw 'Could not parse $pubspecPath:\n${ex.message}';
+    }
+  }
+
   Pubspec(this.name, this.version, this.dependencies, this.environment,
       [Map<String, Object> fields])
     : this.fields = fields == null ? {} : fields;
@@ -44,6 +69,7 @@
   bool get isEmpty =>
     name == null && version == Version.none && dependencies.isEmpty;
 
+  // TODO(rnystrom): Make this a static method to match corelib.
   /// Parses the pubspec whose text is [contents]. If the pubspec doesn't define
   /// version for itself, it defaults to [Version.none].
   factory Pubspec.parse(String contents, SourceRegistry sources) {
diff --git a/utils/pub/resource/certs/cert9.db b/utils/pub/resource/certs/cert9.db
new file mode 100644
index 0000000..955f26d
--- /dev/null
+++ b/utils/pub/resource/certs/cert9.db
Binary files differ
diff --git a/utils/pub/resource/certs/key4.db b/utils/pub/resource/certs/key4.db
new file mode 100644
index 0000000..1b6b97a
--- /dev/null
+++ b/utils/pub/resource/certs/key4.db
Binary files differ
diff --git a/utils/pub/resource/certs/pkcs11.txt b/utils/pub/resource/certs/pkcs11.txt
new file mode 100644
index 0000000..81f899b
--- /dev/null
+++ b/utils/pub/resource/certs/pkcs11.txt
@@ -0,0 +1,5 @@
+library=
+name=NSS Internal PKCS #11 Module
+parameters=configdir='utils/pub/resource/certs' certPrefix='' keyPrefix='' secmod='secmod.db' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription='' 
+NSS=Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] askpw=any timeout=30})
+
diff --git a/utils/pub/sdk_source.dart b/utils/pub/sdk_source.dart
index e0782b0..6fbba09 100644
--- a/utils/pub/sdk_source.dart
+++ b/utils/pub/sdk_source.dart
@@ -10,6 +10,7 @@
 import 'pubspec.dart';
 import 'sdk.dart' as sdk;
 import 'source.dart';
+import 'utils.dart';
 import 'version.dart';
 
 /// A package source that uses libraries from the Dart SDK.
@@ -20,31 +21,31 @@
   /// SDK packages are not individually versioned. Instead, their version is
   /// inferred from the revision number of the SDK itself.
   Future<Pubspec> describe(PackageId id) {
-    return _getPackagePath(id).then((packageDir) {
+    return defer(() {
+      var packageDir = _getPackagePath(id);
       // TODO(rnystrom): What if packageDir is null?
-      return Package.load(id.name, packageDir, systemCache.sources);
-    }).then((package) {
+      var pubspec = new Pubspec.load(id.name, packageDir, systemCache.sources);
       // Ignore the pubspec's version, and use the SDK's.
-      return new Pubspec(id.name, sdk.version, package.pubspec.dependencies,
-          package.pubspec.environment);
+      return new Pubspec(id.name, sdk.version, pubspec.dependencies,
+          pubspec.environment);
     });
   }
 
   /// Since all the SDK files are already available locally, installation just
   /// involves symlinking the SDK library into the packages directory.
   Future<bool> install(PackageId id, String destPath) {
-    return _getPackagePath(id).then((path) {
-      if (path == null) return new Future<bool>.immediate(false);
+    return defer(() {
+      var path = _getPackagePath(id);
+      if (path == null) return false;
 
-      return createPackageSymlink(id.name, path, destPath).then(
-          (_) => true);
+      return createPackageSymlink(id.name, path, destPath).then((_) => true);
     });
   }
 
   /// Gets the path in the SDK's "pkg" directory to the directory containing
   /// package [id]. Returns `null` if the package could not be found.
-  Future<String> _getPackagePath(PackageId id) {
+  String _getPackagePath(PackageId id) {
     var pkgPath = join(sdk.rootDirectory, "pkg", id.description);
-    return dirExists(pkgPath).then((found) => found ? pkgPath : null);
+    return dirExists(pkgPath) ? pkgPath : null;
   }
 }
diff --git a/utils/pub/source.dart b/utils/pub/source.dart
index 211f0dba..777c1a0 100644
--- a/utils/pub/source.dart
+++ b/utils/pub/source.dart
@@ -9,6 +9,7 @@
 import 'package.dart';
 import 'pubspec.dart';
 import 'system_cache.dart';
+import 'utils.dart';
 import 'version.dart';
 
 /// A source from which to install packages.
@@ -104,13 +105,15 @@
   ///
   /// By default, this uses [systemCacheDirectory] and [install].
   Future<Package> installToSystemCache(PackageId id) {
-    var path = systemCacheDirectory(id);
-    return exists(path).then((exists) {
-      if (exists) return new Future<bool>.immediate(true);
-      return ensureDir(dirname(path)).then((_) => install(id, path));
+    var path;
+    return systemCacheDirectory(id).then((p) {
+      path = p;
+      if (dirExists(path)) return true;
+      ensureDir(dirname(path));
+      return install(id, path);
     }).then((found) {
       if (!found) throw 'Package $id not found.';
-      return Package.load(id.name, path, systemCache.sources);
+      return new Package.load(id.name, path, systemCache.sources);
     });
   }
 
@@ -118,11 +121,10 @@
   /// [id] should be installed to. This should return a path to a subdirectory
   /// of [systemCacheRoot].
   ///
-  /// This doesn't need to be implemented if [shouldCache] is false, or if
-  /// [installToSystemCache] is implemented.
-  String systemCacheDirectory(PackageId id) {
-    throw 'Source.systemCacheDirectory must be implemented if shouldCache is '
-        'true and installToSystemCache is not implemented.';
+  /// This doesn't need to be implemented if [shouldCache] is false.
+  Future<String> systemCacheDirectory(PackageId id) {
+    return new Future.immediateError(
+        "systemCacheDirectory() must be implemented if shouldCache is true.");
   }
 
   /// When a [Pubspec] or [LockFile] is parsed, it reads in the description for
diff --git a/utils/pub/system_cache.dart b/utils/pub/system_cache.dart
index 1e26554..4041e40 100644
--- a/utils/pub/system_cache.dart
+++ b/utils/pub/system_cache.dart
@@ -13,6 +13,7 @@
 import 'io.dart' as io show createTempDir;
 import 'log.dart' as log;
 import 'package.dart';
+import 'pubspec.dart';
 import 'sdk_source.dart';
 import 'source.dart';
 import 'source_registry.dart';
@@ -59,6 +60,21 @@
     sources.register(source);
   }
 
+  /// Gets the package identified by [id]. If the package is already cached,
+  /// reads it from the cache. Otherwise, requests it from the source.
+  Future<Pubspec> describe(PackageId id) {
+    // Try to get it from the system cache first.
+    if (id.source.shouldCache) {
+      return id.systemCacheDirectory.then((packageDir) {
+        if (!dirExists(packageDir)) return id.describe();
+        return new Pubspec.load(id.name, packageDir, sources);
+      });
+    }
+
+    // Not cached, so get it from the source.
+    return id.describe();
+  }
+
   /// Ensures that the package identified by [id] is installed to the cache,
   /// loads it, and returns it.
   ///
@@ -84,7 +100,8 @@
   /// temp directory to ensure that it's on the same volume as the pub system
   /// cache so that it can move the directory from it.
   Future<Directory> createTempDir() {
-    return ensureDir(tempDir).then((temp) {
+    return defer(() {
+      var temp = ensureDir(tempDir);
       return io.createTempDir(join(temp, 'dir'));
     });
   }
@@ -92,8 +109,8 @@
   /// Delete's the system cache's internal temp directory.
   Future deleteTempDir() {
     log.fine('Clean up system cache temp directory $tempDir.');
-    return dirExists(tempDir).then((exists) {
-      if (!exists) return;
+    return defer(() {
+      if (!dirExists(tempDir)) return;
       return deleteDir(tempDir);
     });
   }
diff --git a/utils/pub/utils.dart b/utils/pub/utils.dart
index 4311c09..38fa490 100644
--- a/utils/pub/utils.dart
+++ b/utils/pub/utils.dart
@@ -27,6 +27,47 @@
   int get hashCode => first.hashCode ^ last.hashCode;
 }
 
+/// A completer that waits until all added [Future]s complete.
+// TODO(rnystrom): Copied from web_components. Remove from here when it gets
+// added to dart:core. (See #6626.)
+class FutureGroup<T> {
+  int _pending = 0;
+  Completer<List<T>> _completer = new Completer<List<T>>();
+  final List<Future<T>> futures = <Future<T>>[];
+  bool completed = false;
+
+  final List<T> _values = <T>[];
+
+  /// Wait for [task] to complete.
+  Future<T> add(Future<T> task) {
+    if (completed) {
+      throw new StateError("The FutureGroup has already completed.");
+    }
+
+    _pending++;
+    futures.add(task.then((value) {
+      if (completed) return;
+
+      _pending--;
+      _values.add(value);
+
+      if (_pending <= 0) {
+        completed = true;
+        _completer.complete(_values);
+      }
+    }).catchError((e) {
+      if (completed) return;
+
+      completed = true;
+      _completer.completeError(e.error, e.stackTrace);
+    }));
+
+    return task;
+  }
+
+  Future<List> get future => _completer.future;
+}
+
 // TODO(rnystrom): Move into String?
 /// Pads [source] to [length] by adding spaces at the end.
 String padRight(String source, int length) {
@@ -104,6 +145,16 @@
   return CryptoUtils.bytesToHex(sha.close());
 }
 
+/// Invokes the given callback asynchronously. Returns a [Future] that completes
+/// to the result of [callback].
+///
+/// This is also used to wrap synchronous code that may thrown an exception to
+/// ensure that methods that have both sync and async code only report errors
+/// asynchronously.
+Future defer(callback()) {
+  return new Future.immediate(null).then((_) => callback());
+}
+
 /// Returns a [Future] that completes in [milliseconds].
 Future sleep(int milliseconds) {
   var completer = new Completer();
@@ -118,6 +169,97 @@
       onError: (e) => completer.completeError(e.error, e.stackTrace));
 }
 
+// TODO(nweiz): remove this when issue 7964 is fixed.
+/// Returns a [Future] that will complete to the first element of [stream].
+/// Unlike [Stream.first], this is safe to use with single-subscription streams.
+Future streamFirst(Stream stream) {
+  var completer = new Completer();
+  var subscription;
+  subscription = stream.listen((value) {
+    subscription.cancel();
+    completer.complete(value);
+  },
+      onError: (e) => completer.completeError(e.error, e.stackTrace),
+      onDone: () => completer.completeError(new StateError("No elements")),
+      unsubscribeOnError: true);
+  return completer.future;
+}
+
+/// Returns a wrapped version of [stream] along with a [StreamSubscription] that
+/// can be used to control the wrapped stream.
+Pair<Stream, StreamSubscription> streamWithSubscription(Stream stream) {
+  var controller = stream.isBroadcast ?
+      new StreamController.broadcast() :
+      new StreamController();
+  var subscription = stream.listen(controller.add,
+      onError: controller.signalError,
+      onDone: controller.close);
+  return new Pair<Stream, StreamSubscription>(controller.stream, subscription);
+}
+
+// TODO(nweiz): remove this when issue 7787 is fixed.
+/// Creates two single-subscription [Stream]s that each emit all values and
+/// errors from [stream]. This is useful if [stream] is single-subscription but
+/// multiple subscribers are necessary.
+Pair<Stream, Stream> tee(Stream stream) {
+  var controller1 = new StreamController();
+  var controller2 = new StreamController();
+  stream.listen((value) {
+    controller1.add(value);
+    controller2.add(value);
+  }, onError: (error) {
+    controller1.signalError(error);
+    controller2.signalError(error);
+  }, onDone: () {
+    controller1.close();
+    controller2.close();
+  });
+  return new Pair<Stream, Stream>(controller1.stream, controller2.stream);
+}
+
+/// A regular expression matching a line termination character or character
+/// sequence.
+final RegExp _lineRegexp = new RegExp(r"\r\n|\r|\n");
+
+/// Converts a stream of arbitrarily chunked strings into a line-by-line stream.
+/// The lines don't include line termination characters. A single trailing
+/// newline is ignored.
+Stream<String> streamToLines(Stream<String> stream) {
+  var buffer = new StringBuffer();
+  return wrapStream(stream.transform(new StreamTransformer(
+      handleData: (chunk, sink) {
+        var lines = chunk.split(_lineRegexp);
+        var leftover = lines.removeLast();
+        for (var line in lines) {
+          if (!buffer.isEmpty) {
+            buffer.add(line);
+            line = buffer.toString();
+            buffer.clear();
+          }
+
+          sink.add(line);
+        }
+        buffer.add(leftover);
+      },
+      handleDone: (sink) {
+        if (!buffer.isEmpty) sink.add(buffer.toString());
+        sink.close();
+      })));
+}
+
+// TODO(nweiz): remove this when issue 8310 is fixed.
+/// Returns a [Stream] identical to [stream], but piped through a new
+/// [StreamController]. This exists to work around issue 8310.
+Stream wrapStream(Stream stream) {
+  var controller = stream.isBroadcast
+      ? new StreamController.broadcast()
+      : new StreamController();
+  stream.listen(controller.add,
+      onError: (e) => controller.signalError(e),
+      onDone: controller.close);
+  return controller.stream;
+}
+
 /// Like [Iterable.where], but allows [test] to return [Future]s and uses the
 /// results of those [Future]s as the test.
 Future<Iterable> futureWhere(Iterable iter, test(value)) {
diff --git a/utils/pub/validator/compiled_dartdoc.dart b/utils/pub/validator/compiled_dartdoc.dart
index c2c93f3..e5a7353 100644
--- a/utils/pub/validator/compiled_dartdoc.dart
+++ b/utils/pub/validator/compiled_dartdoc.dart
@@ -21,27 +21,26 @@
 
   Future validate() {
     return listDir(entrypoint.root.dir, recursive: true).then((entries) {
-      return futureWhere(entries, (entry) {
+      for (var entry in entries) {
         if (basename(entry) != "nav.json") return false;
         var dir = dirname(entry);
 
         // Look for tell-tale Dartdoc output files all in the same directory.
-        return Future.wait([
-          fileExists(entry),
-          fileExists(join(dir, "index.html")),
-          fileExists(join(dir, "styles.css")),
-          fileExists(join(dir, "dart-logo-small.png")),
-          fileExists(join(dir, "client-live-nav.js"))
-        ]).then((results) => results.every((val) => val));
-      }).then((files) {
-        for (var dartdocDir in files.mappedBy(dirname)) {
-          var relativePath = path.relative(dartdocDir);
+        var files = [
+          entry,
+          join(dir, "index.html"),
+          join(dir, "styles.css"),
+          join(dir, "dart-logo-small.png"),
+          join(dir, "client-live-nav.js")
+        ];
+
+        if (files.every((val) => fileExists(val))) {
           warnings.add("Avoid putting generated documentation in "
-                  "$relativePath.\n"
+                  "${path.relative(dir)}.\n"
               "Generated documentation bloats the package with redundant "
                   "data.");
         }
-      });
+      }
     });
   }
 }
diff --git a/utils/pub/validator/dependency.dart b/utils/pub/validator/dependency.dart
index 18cff66..a848c54 100644
--- a/utils/pub/validator/dependency.dart
+++ b/utils/pub/validator/dependency.dart
@@ -38,7 +38,7 @@
           // should warn about unittest. Until then, it's reasonable not to put
           // a constraint on it.
           dependency.name != 'unittest') {
-        return _warnAboutConstraint(dependency);
+        _warnAboutConstraint(dependency);
       }
 
       return new Future.immediate(null);
@@ -74,21 +74,20 @@
   }
 
   /// Warn that dependencies should have version constraints.
-  Future _warnAboutConstraint(PackageRef ref) {
-    return entrypoint.loadLockFile().then((lockFile) {
-      var message = 'Your dependency on "${ref.name}" should have a version '
-          'constraint.';
-      var locked = lockFile.packages[ref.name];
-      if (locked != null) {
-        message = '$message For example:\n'
-          '\n'
-          'dependencies:\n'
-          '  ${ref.name}: ${_constraintForVersion(locked.version)}\n';
-      }
-      warnings.add("$message\n"
-          "Without a constraint, you're promising to support all future "
-          "versions of ${ref.name}.");
-    });
+  void _warnAboutConstraint(PackageRef ref) {
+    var lockFile = entrypoint.loadLockFile();
+    var message = 'Your dependency on "${ref.name}" should have a version '
+        'constraint.';
+    var locked = lockFile.packages[ref.name];
+    if (locked != null) {
+      message = '$message For example:\n'
+        '\n'
+        'dependencies:\n'
+        '  ${ref.name}: ${_constraintForVersion(locked.version)}\n';
+    }
+    warnings.add("$message\n"
+        "Without a constraint, you're promising to support all future "
+        "versions of ${ref.name}.");
   }
 
   /// Returns the suggested version constraint for a dependency that was tested
diff --git a/utils/pub/validator/directory.dart b/utils/pub/validator/directory.dart
index 09a6c7e..6ab932c 100644
--- a/utils/pub/validator/directory.dart
+++ b/utils/pub/validator/directory.dart
@@ -8,6 +8,7 @@
 
 import '../entrypoint.dart';
 import '../io.dart';
+import '../utils.dart';
 import '../validator.dart';
 
 /// A validator that validates a package's top-level directories.
@@ -19,29 +20,27 @@
 
   Future validate() {
     return listDir(entrypoint.root.dir).then((dirs) {
-      return Future.wait(dirs.map((dir) {
-        return dirExists(dir).then((exists) {
-          if (!exists) return;
+      for (var dir in dirs) {
+        if (!dirExists(dir)) continue;
 
-          dir = basename(dir);
-          if (_PLURAL_NAMES.contains(dir)) {
-            // Cut off the "s"
-            var singularName = dir.substring(0, dir.length - 1);
-            warnings.add('Rename the top-level "$dir" directory to '
-                    '"$singularName".\n'
-                'The Pub layout convention is to use singular directory '
-                    'names.\n'
-                'Plural names won\'t be correctly identified by Pub and other '
-                    'tools.');
-          }
+        dir = basename(dir);
+        if (_PLURAL_NAMES.contains(dir)) {
+          // Cut off the "s"
+          var singularName = dir.substring(0, dir.length - 1);
+          warnings.add('Rename the top-level "$dir" directory to '
+                  '"$singularName".\n'
+              'The Pub layout convention is to use singular directory '
+                  'names.\n'
+              'Plural names won\'t be correctly identified by Pub and other '
+                  'tools.');
+        }
 
-          if (dir.contains(new RegExp(r"^samples?$"))) {
-            warnings.add('Rename the top-level "$dir" directory to "example".\n'
-                'This allows Pub to find your examples and create "packages" '
-                    'directories for them.\n');
-          }
-        });
-      }));
+        if (dir.contains(new RegExp(r"^samples?$"))) {
+          warnings.add('Rename the top-level "$dir" directory to "example".\n'
+              'This allows Pub to find your examples and create "packages" '
+                  'directories for them.\n');
+        }
+      }
     });
   }
 }
diff --git a/utils/pub/validator/lib.dart b/utils/pub/validator/lib.dart
index faee7290..7346223e 100644
--- a/utils/pub/validator/lib.dart
+++ b/utils/pub/validator/lib.dart
@@ -23,8 +23,8 @@
   Future validate() {
     var libDir = join(entrypoint.root.dir, "lib");
 
-    return dirExists(libDir).then((libDirExists) {
-      if (!libDirExists) {
+    return defer(() {
+      if (!dirExists(libDir)) {
         errors.add('You must have a "lib" directory.\n'
             "Without that, users cannot import any code from your package.");
         return;
diff --git a/utils/pub/validator/name.dart b/utils/pub/validator/name.dart
index 7c4778c..0386089 100644
--- a/utils/pub/validator/name.dart
+++ b/utils/pub/validator/name.dart
@@ -10,6 +10,7 @@
 import '../../../pkg/path/lib/path.dart' as path;
 import '../entrypoint.dart';
 import '../io.dart';
+import '../utils.dart';
 import '../validator.dart';
 
 /// Dart reserved words, from the Dart spec.
@@ -47,8 +48,8 @@
   /// to the package's root directory.
   Future<List<String>> get _libraries {
     var libDir = join(entrypoint.root.dir, "lib");
-    return dirExists(libDir).then((libDirExists) {
-      if (!libDirExists) return [];
+    return defer(() {
+      if (!dirExists(libDir)) return [];
       return listDir(libDir, recursive: true);
     }).then((files) {
       return files
diff --git a/utils/tests/pub/command_line_config.dart b/utils/tests/pub/command_line_config.dart
index 71df35e..d15126b 100644
--- a/utils/tests/pub/command_line_config.dart
+++ b/utils/tests/pub/command_line_config.dart
@@ -10,15 +10,23 @@
 import '../../../pkg/unittest/lib/unittest.dart';
 import '../../pub/utils.dart';
 
-const _GREEN = '\u001b[32m';
-const _RED = '\u001b[31m';
-const _MAGENTA = '\u001b[35m';
-const _NONE = '\u001b[0m';
+/// Gets a "special" string (ANSI escape or Unicode). On Windows, returns
+/// something else since those aren't supported.
+String _getSpecial(String color, [String onWindows = '']) {
+  // No ANSI escapes on windows.
+  if (Platform.operatingSystem == 'windows') return onWindows;
+  return color;
+}
 
 /// Pretty Unicode characters!
-const _CHECKBOX = '\u2713';
-const _BALLOT_X = '\u2717';
-const _LAMBDA   = '\u03bb';
+final _checkbox = _getSpecial('\u2713', 'PASS');
+final _ballotX  = _getSpecial('\u2717', 'FAIL');
+final _lambda   = _getSpecial('\u03bb', '<fn>');
+
+final _green = _getSpecial('\u001b[32m');
+final _red = _getSpecial('\u001b[31m');
+final _magenta = _getSpecial('\u001b[35m');
+final _none = _getSpecial('\u001b[0m');
 
 /// A custom unittest configuration for running the pub tests from the
 /// command-line and generating human-friendly output.
@@ -30,9 +38,9 @@
   void onTestResult(TestCase testCase) {
     var result;
     switch (testCase.result) {
-      case PASS: result = '$_GREEN$_CHECKBOX$_NONE'; break;
-      case FAIL: result = '$_RED$_BALLOT_X$_NONE'; break;
-      case ERROR: result = '$_MAGENTA?$_NONE'; break;
+      case PASS: result = '$_green$_checkbox$_none'; break;
+      case FAIL: result = '$_red$_ballotX$_none'; break;
+      case ERROR: result = '$_magenta?$_none'; break;
     }
     print('$result ${testCase.description}');
 
@@ -51,15 +59,15 @@
     if (uncaughtError != null) {
       print('Top-level uncaught error: $uncaughtError');
     } else if (errors != 0) {
-      print('${_GREEN}$passed${_NONE} passed, ${_RED}$failed${_NONE} failed, '
-            '${_MAGENTA}$errors${_NONE} errors.');
+      print('${_green}$passed${_none} passed, ${_red}$failed${_none} failed, '
+            '${_magenta}$errors${_none} errors.');
     } else if (failed != 0) {
-      print('${_GREEN}$passed${_NONE} passed, ${_RED}$failed${_NONE} '
+      print('${_green}$passed${_none} passed, ${_red}$failed${_none} '
             'failed.');
     } else if (passed == 0) {
       print('No tests found.');
     } else {
-      print('All ${_GREEN}$passed${_NONE} tests passed!');
+      print('All ${_green}$passed${_none} tests passed!');
       success = true;
     }
   }
@@ -154,7 +162,7 @@
       library = path.relative(library);
     }
 
-    var member = match[1].replaceAll("<anonymous closure>", _LAMBDA);
+    var member = match[1].replaceAll("<anonymous closure>", _lambda);
     return new _StackFrame._(isCore, library, match[3], match[4], member);
   }
-}
\ No newline at end of file
+}
diff --git a/utils/tests/pub/curl_client_test.dart b/utils/tests/pub/curl_client_test.dart
deleted file mode 100644
index 924e994..0000000
--- a/utils/tests/pub/curl_client_test.dart
+++ /dev/null
@@ -1,447 +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.
-
-library curl_client_test;
-
-import 'dart:io';
-import 'dart:isolate';
-import 'dart:json' as json;
-import 'dart:uri';
-
-import '../../../pkg/unittest/lib/unittest.dart';
-import '../../../pkg/http/lib/http.dart' as http;
-import '../../pub/curl_client.dart';
-import '../../pub/io.dart';
-import '../../pub/utils.dart';
-
-// TODO(rnystrom): All of the code from here to the first "---..." line was
-// copied from pkg/http/test/utils.dart and pkg/http/lib/src/utils.dart. It's
-// copied here because http/test/utils.dart is now using "package:" imports and
-// this is not. You cannot mix those because you end up with duplicate copies of
-// the same library in memory. Since curl_client is going away soon anyway, I'm
-// just copying the code here. Delete all of this when curl client is removed.
-
-/// Returns the [Encoding] that corresponds to [charset]. Throws a
-/// [FormatException] if no [Encoding] was found that corresponds to [charset].
-/// [charset] may not be null.
-Encoding requiredEncodingForCharset(String charset) {
-  var encoding = _encodingForCharset(charset);
-  if (encoding != null) return encoding;
-  throw new FormatException('Unsupported encoding "$charset".');
-}
-
-/// Returns the [Encoding] that corresponds to [charset]. Returns null if no
-/// [Encoding] was found that corresponds to [charset]. [charset] may not be
-/// null.
-Encoding _encodingForCharset(String charset) {
-  charset = charset.toLowerCase();
-  if (charset == 'ascii' || charset == 'us-ascii') return Encoding.ASCII;
-  if (charset == 'utf-8') return Encoding.UTF_8;
-  if (charset == 'iso-8859-1') return Encoding.ISO_8859_1;
-  return null;
-}
-
-/// Converts [bytes] into a [String] according to [encoding].
-String decodeString(List<int> bytes, Encoding encoding) {
-  // TODO(nweiz): implement this once issue 6284 is fixed.
-  return new String.fromCharCodes(bytes);
-}
-
-/// The current server instance.
-HttpServer _server;
-
-/// The URL for the current server instance.
-Uri get serverUrl => Uri.parse('http://localhost:${_server.port}');
-
-/// A dummy URL for constructing requests that won't be sent.
-Uri get dummyUrl => Uri.parse('http://dartlang.org/');
-
-/// Starts a new HTTP server.
-void startServer() {
-  _server = new HttpServer();
-
-  _server.addRequestHandler((request) => request.path == '/error',
-      (request, response) {
-    response.statusCode = 400;
-    response.contentLength = 0;
-    response.outputStream.close();
-  });
-
-  _server.addRequestHandler((request) => request.path == '/loop',
-      (request, response) {
-    var n = int.parse(Uri.parse(request.uri).query);
-    response.statusCode = 302;
-    response.headers.set('location',
-        serverUrl.resolve('/loop?${n + 1}').toString());
-    response.contentLength = 0;
-    response.outputStream.close();
-  });
-
-  _server.addRequestHandler((request) => request.path == '/redirect',
-      (request, response) {
-    response.statusCode = 302;
-    response.headers.set('location', serverUrl.resolve('/').toString());
-    response.contentLength = 0;
-    response.outputStream.close();
-  });
-
-  _server.defaultRequestHandler = (request, response) {
-    consumeInputStream(request.inputStream).then((requestBodyBytes) {
-      response.statusCode = 200;
-      response.headers.contentType = new ContentType("application", "json");
-
-      var requestBody;
-      if (requestBodyBytes.isEmpty) {
-        requestBody = null;
-      } else if (request.headers.contentType.charset != null) {
-        var encoding = requiredEncodingForCharset(
-            request.headers.contentType.charset);
-        requestBody = decodeString(requestBodyBytes, encoding);
-      } else {
-        requestBody = requestBodyBytes;
-      }
-
-      var content = {
-        'method': request.method,
-        'path': request.path,
-        'headers': {}
-      };
-      if (requestBody != null) content['body'] = requestBody;
-      request.headers.forEach((name, values) {
-        // These headers are automatically generated by dart:io, so we don't
-        // want to test them here.
-        if (name == 'cookie' || name == 'host') return;
-
-        content['headers'][name] = values;
-      });
-
-      var outputEncoding;
-      var encodingName = request.queryParameters['response-encoding'];
-      if (encodingName != null) {
-        outputEncoding = requiredEncodingForCharset(encodingName);
-      } else {
-        outputEncoding = Encoding.ASCII;
-      }
-
-      var body = json.stringify(content);
-      response.contentLength = body.length;
-      response.outputStream.writeString(body, outputEncoding);
-      response.outputStream.close();
-    });
-  };
-
-  _server.listen("127.0.0.1", 0);
-}
-
-/// Stops the current HTTP server.
-void stopServer() {
-  _server.close();
-  _server = null;
-}
-
-/// A matcher that matches JSON that parses to a value that matches the inner
-/// matcher.
-Matcher parse(matcher) => new _Parse(matcher);
-
-class _Parse extends BaseMatcher {
-  final Matcher _matcher;
-
-  _Parse(this._matcher);
-
-  bool matches(item, MatchState matchState) {
-    if (item is! String) return false;
-
-    var parsed;
-    try {
-      parsed = json.parse(item);
-    } catch (e) {
-      return false;
-    }
-
-    return _matcher.matches(parsed, matchState);
-  }
-
-  Description describe(Description description) {
-    return description.add('parses to a value that ')
-      .addDescriptionOf(_matcher);
-  }
-}
-
-/// A matcher for HttpExceptions.
-const isHttpException = const _HttpException();
-
-/// A matcher for functions that throw HttpException.
-const Matcher throwsHttpException =
-    const Throws(isHttpException);
-
-class _HttpException extends TypeMatcher {
-  const _HttpException() : super("HttpException");
-  bool matches(item, MatchState matchState) => item is HttpException;
-}
-
-/// A matcher for RedirectLimitExceededExceptions.
-const isRedirectLimitExceededException =
-    const _RedirectLimitExceededException();
-
-/// A matcher for functions that throw RedirectLimitExceededException.
-const Matcher throwsRedirectLimitExceededException =
-    const Throws(isRedirectLimitExceededException);
-
-class _RedirectLimitExceededException extends TypeMatcher {
-  const _RedirectLimitExceededException() :
-      super("RedirectLimitExceededException");
-
-  bool matches(item, MatchState matchState) =>
-    item is RedirectLimitExceededException;
-}
-
-// ----------------------------------------------------------------------------
-
-void main() {
-  setUp(startServer);
-  tearDown(stopServer);
-
-  test('head', () {
-    expect(new CurlClient().head(serverUrl).then((response) {
-      expect(response.statusCode, equals(200));
-      expect(response.body, equals(''));
-    }), completes);
-  });
-
-  test('get', () {
-    expect(new CurlClient().get(serverUrl, headers: {
-      'X-Random-Header': 'Value',
-      'X-Other-Header': 'Other Value'
-    }).then((response) {
-      expect(response.statusCode, equals(200));
-      expect(response.body, parse(equals({
-        'method': 'GET',
-        'path': '/',
-        'headers': {
-          'x-random-header': ['Value'],
-          'x-other-header': ['Other Value']
-        },
-      })));
-    }), completes);
-  });
-
-  test('post', () {
-    expect(new CurlClient().post(serverUrl, headers: {
-      'X-Random-Header': 'Value',
-      'X-Other-Header': 'Other Value'
-    }, fields: {
-      'some-field': 'value',
-      'other-field': 'other value'
-    }).then((response) {
-      expect(response.statusCode, equals(200));
-      expect(response.body, parse(equals({
-        'method': 'POST',
-        'path': '/',
-        'headers': {
-          'content-type': [
-            'application/x-www-form-urlencoded; charset=UTF-8'
-          ],
-          'content-length': ['40'],
-          'x-random-header': ['Value'],
-          'x-other-header': ['Other Value']
-        },
-        'body': 'some-field=value&other-field=other+value'
-      })));
-    }), completes);
-  });
-
-  test('post without fields', () {
-    expect(new CurlClient().post(serverUrl, headers: {
-      'X-Random-Header': 'Value',
-      'X-Other-Header': 'Other Value',
-      'Content-Type': 'text/plain'
-    }).then((response) {
-      expect(response.statusCode, equals(200));
-      expect(response.body, parse(equals({
-        'method': 'POST',
-        'path': '/',
-        'headers': {
-          'content-type': ['text/plain'],
-          'x-random-header': ['Value'],
-          'x-other-header': ['Other Value']
-        }
-      })));
-    }), completes);
-  });
-
-  test('put', () {
-    expect(new CurlClient().put(serverUrl, headers: {
-      'X-Random-Header': 'Value',
-      'X-Other-Header': 'Other Value'
-    }, fields: {
-      'some-field': 'value',
-      'other-field': 'other value'
-    }).then((response) {
-      expect(response.statusCode, equals(200));
-      expect(response.body, parse(equals({
-        'method': 'PUT',
-        'path': '/',
-        'headers': {
-          'content-type': [
-            'application/x-www-form-urlencoded; charset=UTF-8'
-          ],
-          'content-length': ['40'],
-          'x-random-header': ['Value'],
-          'x-other-header': ['Other Value']
-        },
-        'body': 'some-field=value&other-field=other+value'
-      })));
-    }), completes);
-  });
-
-  test('put without fields', () {
-    expect(new CurlClient().put(serverUrl, headers: {
-      'X-Random-Header': 'Value',
-      'X-Other-Header': 'Other Value',
-      'Content-Type': 'text/plain'
-    }).then((response) {
-      expect(response.statusCode, equals(200));
-      expect(response.body, parse(equals({
-        'method': 'PUT',
-        'path': '/',
-        'headers': {
-          'content-type': ['text/plain'],
-          'x-random-header': ['Value'],
-          'x-other-header': ['Other Value']
-        }
-      })));
-    }), completes);
-  });
-
-  test('delete', () {
-    expect(new CurlClient().delete(serverUrl, headers: {
-      'X-Random-Header': 'Value',
-      'X-Other-Header': 'Other Value'
-    }).then((response) {
-      expect(response.statusCode, equals(200));
-      expect(response.body, parse(equals({
-        'method': 'DELETE',
-        'path': '/',
-        'headers': {
-          'x-random-header': ['Value'],
-          'x-other-header': ['Other Value']
-        }
-      })));
-    }), completes);
-  });
-
-  test('read', () {
-    expect(new CurlClient().read(serverUrl, headers: {
-      'X-Random-Header': 'Value',
-      'X-Other-Header': 'Other Value'
-    }), completion(parse(equals({
-      'method': 'GET',
-      'path': '/',
-      'headers': {
-        'x-random-header': ['Value'],
-        'x-other-header': ['Other Value']
-      },
-    }))));
-  });
-
-  test('read throws an error for a 4** status code', () {
-    expect(new CurlClient().read(serverUrl.resolve('/error')),
-        throwsHttpException);
-  });
-
-  test('readBytes', () {
-    var future = new CurlClient().readBytes(serverUrl, headers: {
-      'X-Random-Header': 'Value',
-      'X-Other-Header': 'Other Value'
-    }).then((bytes) => new String.fromCharCodes(bytes));
-
-    expect(future, completion(parse(equals({
-      'method': 'GET',
-      'path': '/',
-      'headers': {
-        'x-random-header': ['Value'],
-        'x-other-header': ['Other Value']
-      },
-    }))));
-  });
-
-  test('readBytes throws an error for a 4** status code', () {
-    expect(new CurlClient().readBytes(serverUrl.resolve('/error')),
-        throwsHttpException);
-  });
-
-  test('#send a StreamedRequest', () {
-    var client = new CurlClient();
-    var request = new http.StreamedRequest("POST", serverUrl);
-    request.headers[HttpHeaders.CONTENT_TYPE] =
-      'application/json; charset=utf-8';
-
-    var future = client.send(request).then((response) {
-      expect(response.statusCode, equals(200));
-      return response.stream.bytesToString();
-    }).whenComplete(client.close);
-
-    expect(future, completion(parse(equals({
-      'method': 'POST',
-      'path': '/',
-      'headers': {
-        'content-type': ['application/json; charset=utf-8'],
-        'transfer-encoding': ['chunked']
-      },
-      'body': '{"hello": "world"}'
-    }))));
-
-    request.sink.add('{"hello": "world"}'.charCodes);
-    request.sink.close();
-  });
-
-  test('with one redirect', () {
-    var url = serverUrl.resolve('/redirect');
-    expect(new CurlClient().get(url).then((response) {
-      expect(response.statusCode, equals(200));
-      expect(response.body, parse(equals({
-        'method': 'GET',
-        'path': '/',
-        'headers': {}
-      })));
-    }), completes);
-  });
-
-  test('with too many redirects', () {
-    expect(new CurlClient().get(serverUrl.resolve('/loop?1')),
-        throwsRedirectLimitExceededException);
-  });
-
-  test('with a generic failure', () {
-    expect(new CurlClient().get('url fail'),
-        throwsHttpException);
-  });
-
-  test('with one redirect via HEAD', () {
-    var url = serverUrl.resolve('/redirect');
-    expect(new CurlClient().head(url).then((response) {
-      expect(response.statusCode, equals(200));
-    }), completes);
-  });
-
-  test('with too many redirects via HEAD', () {
-    expect(new CurlClient().head(serverUrl.resolve('/loop?1')),
-        throwsRedirectLimitExceededException);
-  });
-
-  test('with a generic failure via HEAD', () {
-    expect(new CurlClient().head('url fail'),
-        throwsHttpException);
-  });
-
-  test('without following redirects', () {
-    var request = new http.Request('GET', serverUrl.resolve('/redirect'));
-    request.followRedirects = false;
-    expect(new CurlClient().send(request).then(http.Response.fromStream)
-        .then((response) {
-      expect(response.statusCode, equals(302));
-      expect(response.isRedirect, true);
-    }), completes);
-  });
-}
diff --git a/utils/tests/pub/install/git/check_out_transitive_test.dart b/utils/tests/pub/install/git/check_out_transitive_test.dart
index 9f93e09..c0e7b8d 100644
--- a/utils/tests/pub/install/git/check_out_transitive_test.dart
+++ b/utils/tests/pub/install/git/check_out_transitive_test.dart
@@ -14,7 +14,7 @@
 
     git('foo.git', [
       libDir('foo'),
-      libPubspec('foo', '1.0.0', [{"git": "../bar.git"}])
+      libPubspec('foo', '1.0.0', deps: [{"git": "../bar.git"}])
     ]).scheduleCreate();
 
     git('bar.git', [
diff --git a/utils/tests/pub/install/pub_install_test.dart b/utils/tests/pub/install/pub_install_test.dart
index 72e379a..233b7c2 100644
--- a/utils/tests/pub/install/pub_install_test.dart
+++ b/utils/tests/pub/install/pub_install_test.dart
@@ -67,7 +67,6 @@
   integration('does not add a package if it does not have a "lib" directory', () {
     // Using an SDK source, but this should be true of all sources.
     dir(sdkPath, [
-      file('version', '0.1.2.3'),
       dir('pkg', [
         dir('foo', [
           libPubspec('foo', '0.0.0-not.used')
diff --git a/utils/tests/pub/install/sdk/check_out_test.dart b/utils/tests/pub/install/sdk/check_out_test.dart
index 0ee41a5..8d2521b 100644
--- a/utils/tests/pub/install/sdk/check_out_test.dart
+++ b/utils/tests/pub/install/sdk/check_out_test.dart
@@ -11,7 +11,6 @@
 main() {
   integration('checks out a package from the SDK', () {
     dir(sdkPath, [
-      file('version', '0.1.2.3'),
       dir('pkg', [
         dir('foo', [
           libDir('foo', 'foo 0.1.2+3'),
diff --git a/utils/tests/pub/install/sdk/check_out_transitive_test.dart b/utils/tests/pub/install/sdk/check_out_transitive_test.dart
index 5a3156e..88454b0 100644
--- a/utils/tests/pub/install/sdk/check_out_transitive_test.dart
+++ b/utils/tests/pub/install/sdk/check_out_transitive_test.dart
@@ -11,11 +11,10 @@
 main() {
   integration('includes transitive dependencies', () {
     dir(sdkPath, [
-      file('version', '0.1.2.3'),
       dir('pkg', [
         dir('foo', [
           libDir('foo', 'foo 0.1.2+3'),
-          libPubspec('foo', '0.0.0-not.used', [{'sdk': 'bar'}])
+          libPubspec('foo', '0.0.0-not.used', deps: [{'sdk': 'bar'}])
         ]),
         dir('bar', [
           libDir('bar', 'bar 0.1.2+3'),
diff --git a/utils/tests/pub/io_test.dart b/utils/tests/pub/io_test.dart
index 94e8a52..6c6922c 100644
--- a/utils/tests/pub/io_test.dart
+++ b/utils/tests/pub/io_test.dart
@@ -6,16 +6,22 @@
 
 import '../../../pkg/unittest/lib/unittest.dart';
 import '../../pub/io.dart';
+import '../../pub/utils.dart';
+import 'test_pub.dart';
 
 main() {
+  initConfig();
+
   group('listDir', () {
     test('lists a simple directory non-recursively', () {
       expect(withTempDir((path) {
-        var future = writeTextFile(join(path, 'file1.txt'), '')
-            .then((_) => writeTextFile(join(path, 'file2.txt'), ''))
-            .then((_) => createDir(join(path, 'subdir')))
-            .then((_) => writeTextFile(join(path, 'subdir', 'file3.txt'), ''))
-            .then((_) => listDir(path));
+        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);
+        });
         expect(future, completion(unorderedEquals([
           join(path, 'file1.txt'),
           join(path, 'file2.txt'),
@@ -27,16 +33,19 @@
 
     test('lists a simple directory recursively', () {
       expect(withTempDir((path) {
-        var future = writeTextFile(join(path, 'file1.txt'), '')
-            .then((_) => writeTextFile(join(path, 'file2.txt'), ''))
-            .then((_) => createDir(join(path, 'subdir')))
-            .then((_) => writeTextFile(join(path, 'subdir', 'file3.txt'), ''))
-            .then((_) => listDir(path, recursive: true));
+        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);
+        });
+
         expect(future, completion(unorderedEquals([
           join(path, 'file1.txt'),
           join(path, 'file2.txt'),
           join(path, 'subdir'),
-          join(path, 'subdir/file3.txt'),
+          join(path, 'subdir', 'file3.txt'),
         ])));
         return future;
       }), completes);
@@ -44,12 +53,14 @@
 
     test('ignores hidden files by default', () {
       expect(withTempDir((path) {
-        var future = writeTextFile(join(path, 'file1.txt'), '')
-            .then((_) => writeTextFile(join(path, 'file2.txt'), ''))
-            .then((_) => writeTextFile(join(path, '.file3.txt'), ''))
-            .then((_) => createDir(join(path, '.subdir')))
-            .then((_) => writeTextFile(join(path, '.subdir', 'file3.txt'), ''))
-            .then((_) => listDir(path, recursive: true));
+        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);
+        });
         expect(future, completion(unorderedEquals([
           join(path, 'file1.txt'),
           join(path, 'file2.txt')
@@ -60,20 +71,20 @@
 
     test('includes hidden files when told to', () {
       expect(withTempDir((path) {
-        var future = writeTextFile(join(path, 'file1.txt'), '')
-            .then((_) => writeTextFile(join(path, 'file2.txt'), ''))
-            .then((_) => writeTextFile(join(path, '.file3.txt'), ''))
-            .then((_) => createDir(join(path, '.subdir')))
-            .then((_) => writeTextFile(join(path, '.subdir', 'file3.txt'), ''))
-            .then((_) {
-              return listDir(path, recursive: true, includeHiddenFiles: true);
-            });
+        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);
+        });
         expect(future, completion(unorderedEquals([
           join(path, 'file1.txt'),
           join(path, 'file2.txt'),
           join(path, '.file3.txt'),
           join(path, '.subdir'),
-          join(path, '.subdir/file3.txt')
+          join(path, '.subdir', 'file3.txt')
         ])));
         return future;
       }), completes);
@@ -82,23 +93,26 @@
     test('returns the unresolved paths for symlinks', () {
       expect(withTempDir((path) {
         var dirToList = join(path, 'dir-to-list');
-        var future = writeTextFile(join(path, 'file1.txt'), '')
-            .then((_) => writeTextFile(join(path, 'file2.txt'), ''))
-            .then((_) => createDir(dirToList))
-            .then((_) {
-              return createSymlink(
-                  join(path, 'file1.txt'),
-                  join(dirToList, 'link1'));
-            }).then((_) => createDir(join(dirToList, 'subdir')))
-            .then((_) {
-              return createSymlink(
-                  join(path, 'file2.txt'),
-                  join(dirToList, 'subdir', 'link2'));
-            }).then((_) => listDir(dirToList, recursive: true));
+        var future = defer(() {
+          createDir(join(path, 'dir1'));
+          writeTextFile(join(path, 'dir1', 'file1.txt'), '');
+          createDir(join(path, 'dir2'));
+          writeTextFile(join(path, 'dir2', 'file2.txt'), '');
+          createDir(dirToList);
+          return createSymlink(join(path, 'dir1'),
+                               join(dirToList, 'linked-dir1'));
+        }).then((_) {
+          createDir(join(dirToList, 'subdir'));
+          return createSymlink(
+                  join(path, 'dir2'),
+                  join(dirToList, 'subdir', 'linked-dir2'));
+        }).then((_) => listDir(dirToList, recursive: true));
         expect(future, completion(unorderedEquals([
-          join(dirToList, 'link1'),
+          join(dirToList, 'linked-dir1'),
+          join(dirToList, 'linked-dir1', 'file1.txt'),
           join(dirToList, 'subdir'),
-          join(dirToList, 'subdir/link2'),
+          join(dirToList, 'subdir', 'linked-dir2'),
+          join(dirToList, 'subdir', 'linked-dir2', 'file2.txt'),
         ])));
         return future;
       }), completes);
@@ -106,9 +120,10 @@
 
     test('works with recursive symlinks', () {
       expect(withTempDir((path) {
-        var future = writeTextFile(join(path, 'file1.txt'), '')
-            .then((_) => createSymlink(path, join(path, 'linkdir')))
-            .then((_) => listDir(path, recursive: true));
+        var future = defer(() {
+          writeTextFile(join(path, 'file1.txt'), '');
+          return createSymlink(path, join(path, 'linkdir'));
+        }).then((_) => listDir(path, recursive: true));
         expect(future, completion(unorderedEquals([
           join(path, 'file1.txt'),
           join(path, 'linkdir')
diff --git a/utils/tests/pub/oauth2_test.dart b/utils/tests/pub/oauth2_test.dart
index e5ff4bc..62d4f91 100644
--- a/utils/tests/pub/oauth2_test.dart
+++ b/utils/tests/pub/oauth2_test.dart
@@ -31,7 +31,9 @@
       response.outputStream.close();
     });
 
-    pub.kill();
+    // After we give pub an invalid response, it should crash. We wait for it to
+    // do so rather than killing it so it'll write out the credentials file.
+    pub.shouldExit(1);
 
     credentialsFile(server, 'access token').scheduleValidate();
   });
@@ -64,7 +66,7 @@
     confirmPublish(pub);
 
     server.handle('POST', '/token', (request, response) {
-      return consumeInputStream(request.inputStream).then((bytes) {
+      return wrapInputStream(request.inputStream).toBytes().then((bytes) {
         var body = new String.fromCharCodes(bytes);
         expect(body, matches(
             new RegExp(r'(^|&)refresh_token=refresh\+token(&|$)')));
@@ -112,7 +114,9 @@
       response.outputStream.close();
     });
 
-    pub.kill();
+    // After we give pub an invalid response, it should crash. We wait for it to
+    // do so rather than killing it so it'll write out the credentials file.
+    pub.shouldExit(1);
 
     credentialsFile(server, 'new access token').scheduleValidate();
   });
@@ -135,7 +139,10 @@
       response.outputStream.close();
     });
 
-    pub.kill();
+
+    // After we give pub an invalid response, it should crash. We wait for it to
+    // do so rather than killing it so it'll write out the credentials file.
+    pub.shouldExit(1);
 
     credentialsFile(server, 'new access token').scheduleValidate();
   });
@@ -190,7 +197,7 @@
       .send();
   }).then((response) {
     expect(response.headers['location'],
-        equals(['http://pub.dartlang.org/authorized']));
+        equals('http://pub.dartlang.org/authorized'));
   }), anything);
 
   handleAccessTokenRequest(server, accessToken);
@@ -198,7 +205,7 @@
 
 void handleAccessTokenRequest(ScheduledServer server, String accessToken) {
   server.handle('POST', '/token', (request, response) {
-    return consumeInputStream(request.inputStream).then((bytes) {
+    return wrapInputStream(request.inputStream).toBytes().then((bytes) {
       var body = new String.fromCharCodes(bytes);
       expect(body, matches(new RegExp(r'(^|&)code=access\+code(&|$)')));
 
diff --git a/utils/tests/pub/pub.status b/utils/tests/pub/pub.status
index ab958ef..af538af 100644
--- a/utils/tests/pub/pub.status
+++ b/utils/tests/pub/pub.status
@@ -2,11 +2,6 @@
 # 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.
 
-pub_uploader_test: Pass, Fail # Issue 7905
-pub_lish_test: Pass, Fail # Issue 7905
-oauth2_test: Pass, Fail, Timeout # Issue 7905, 7920
-curl_client_test: Pass, Fail # Issue 7920
-
 # Pub only runs on the VM, so just rule out all compilers.
 [ $compiler == dart2js || $compiler == dart2dart || $compiler == dartc ]
 *: Skip
@@ -16,4 +11,4 @@
 *: Skip
 
 [ $system == windows ]
-io_test: Fail, Pass, Timeout # Issue 7505
+io_test: Timeout # Issue 7505
diff --git a/utils/tests/pub/pub_lish_test.dart b/utils/tests/pub/pub_lish_test.dart
index e315fff..7101d91 100644
--- a/utils/tests/pub/pub_lish_test.dart
+++ b/utils/tests/pub/pub_lish_test.dart
@@ -47,6 +47,7 @@
 }
 
 main() {
+  initConfig();
   setUp(() => normalPackage.scheduleCreate());
 
   integration('archives and uploads a package', () {
diff --git a/utils/tests/pub/pub_test.dart b/utils/tests/pub/pub_test.dart
index 6de4dbc..bbc8e40 100644
--- a/utils/tests/pub/pub_test.dart
+++ b/utils/tests/pub/pub_test.dart
@@ -55,10 +55,6 @@
   });
 
   integration('running pub with just --version displays version', () {
-    dir(sdkPath, [
-      file('version', '0.1.2.3'),
-    ]).scheduleCreate();
-
     schedulePub(args: ['--version'], output: VERSION_STRING);
   });
 
@@ -125,10 +121,6 @@
 
   group('version', () {
     integration('displays the current version', () {
-      dir(sdkPath, [
-        file('version', '0.1.2.3'),
-      ]).scheduleCreate();
-
       schedulePub(args: ['version'], output: VERSION_STRING);
     });
 
diff --git a/utils/tests/pub/pub_uploader_test.dart b/utils/tests/pub/pub_uploader_test.dart
index fa585af..2ac8722 100644
--- a/utils/tests/pub/pub_uploader_test.dart
+++ b/utils/tests/pub/pub_uploader_test.dart
@@ -54,7 +54,7 @@
     var pub = startPubUploader(server, ['--package', 'pkg', 'add', 'email']);
 
     server.handle('POST', '/packages/pkg/uploaders.json', (request, response) {
-      expect(consumeInputStream(request.inputStream).then((bodyBytes) {
+      expect(wrapInputStream(request.inputStream).toBytes().then((bodyBytes) {
         expect(new String.fromCharCodes(bodyBytes), equals('email=email'));
 
         response.headers.contentType = new ContentType("application", "json");
diff --git a/utils/tests/pub/sdk_constraint_test.dart b/utils/tests/pub/sdk_constraint_test.dart
new file mode 100644
index 0000000..3f934b9
--- /dev/null
+++ b/utils/tests/pub/sdk_constraint_test.dart
@@ -0,0 +1,121 @@
+// 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.
+
+library check_sdk_test;
+
+import "test_pub.dart";
+import "../../../pkg/unittest/lib/unittest.dart";
+
+main() {
+  initConfig();
+
+  for (var command in ["install", "update"]) {
+    var success = new RegExp(r"Dependencies installed!$");
+    if (command == "update") {
+      success = new RegExp(r"Dependencies updated!$");
+    }
+
+    integration("gives a friendly message if there are no constraints", () {
+      dir(appPath, [
+        pubspec({"name": "myapp"}),
+      ]).scheduleCreate();
+
+      schedulePub(args: [command], output: success);
+    });
+
+    integration("gives an error if the root package does not match", () {
+      dir(appPath, [
+        pubspec({
+          "name": "myapp",
+          "environment": {"sdk": ">2.0.0"}
+        })
+      ]).scheduleCreate();
+
+      schedulePub(args: [command],
+          error:
+            """
+            Some packages are not compatible with your SDK version 0.1.2+3:
+            - 'myapp' requires >2.0.0
+
+            You may be able to resolve this by upgrading to the latest Dart SDK
+            or adding a version constraint to use an older version of a package.
+            """);
+    });
+
+    integration("gives an error if some dependencies do not match", () {
+      // Using an SDK source, but this should be true of all sources.
+      dir(sdkPath, [
+        dir("pkg", [
+          dir("foo", [
+            libPubspec("foo", "0.0.1", sdk: ">0.1.3"),
+            libDir("foo")
+          ]),
+          dir("bar", [
+            libPubspec("bar", "0.0.1", sdk: ">0.1.1"),
+            libDir("bar")
+          ])
+        ])
+      ]).scheduleCreate();
+
+      dir(appPath, [
+        pubspec({
+          "name": "myapp",
+          "dependencies": {
+            "foo": { "sdk": "foo" },
+            "bar": { "sdk": "bar" }
+          },
+          "environment": {"sdk": ">2.0.0"}
+        })
+      ]).scheduleCreate();
+
+      schedulePub(args: [command],
+          error:
+            """
+            Some packages are not compatible with your SDK version 0.1.2+3:
+            - 'myapp' requires >2.0.0
+            - 'foo' requires >0.1.3
+
+            You may be able to resolve this by upgrading to the latest Dart SDK
+            or adding a version constraint to use an older version of a package.
+            """);
+    });
+
+    integration("gives an error if a transitive dependency doesn't match", () {
+      // Using an SDK source, but this should be true of all sources.
+      dir(sdkPath, [
+        dir("pkg", [
+          dir("foo", [
+            libPubspec("foo", "0.0.1", deps: [
+              {"sdk": "bar"}
+            ]),
+            libDir("foo")
+          ]),
+          dir("bar", [
+            libPubspec("bar", "0.0.1", sdk: "<0.1.1"),
+            libDir("bar")
+          ])
+        ])
+      ]).scheduleCreate();
+
+      dir(appPath, [
+        pubspec({
+          "name": "myapp",
+          "dependencies": {
+            "foo": { "sdk": "foo" }
+          }
+        })
+      ]).scheduleCreate();
+
+      schedulePub(args: [command],
+          error:
+            """
+            Some packages are not compatible with your SDK version 0.1.2+3:
+            - 'bar' requires <0.1.1
+
+            You may be able to resolve this by upgrading to the latest Dart SDK
+            or adding a version constraint to use an older version of a package.
+            """);
+    });
+  }
+}
diff --git a/utils/tests/pub/test_pub.dart b/utils/tests/pub/test_pub.dart
index 27708ff..c799ce7 100644
--- a/utils/tests/pub/test_pub.dart
+++ b/utils/tests/pub/test_pub.dart
@@ -115,8 +115,7 @@
           return;
         }
 
-        var future = consumeInputStream(stream);
-        future.then((data) {
+        stream.toBytes().then((data) {
           response.statusCode = 200;
           response.contentLength = data.length;
           response.outputStream.write(data);
@@ -243,9 +242,19 @@
 }
 
 /// Describes a file named `pubspec.yaml` for a library package with the given
-/// [name], [version], and [dependencies].
-Descriptor libPubspec(String name, String version, [List dependencies]) =>
-  pubspec(package(name, version, dependencies));
+/// [name], [version], and [deps]. If "sdk" is given, then it adds an SDK
+/// constraint on that version.
+Descriptor libPubspec(String name, String version, {List deps, String sdk}) {
+  var map = package(name, version, deps);
+
+  if (sdk != null) {
+    map["environment"] = {
+      "sdk": sdk
+    };
+  }
+
+  return pubspec(map);
+}
 
 /// Describes a directory named `lib` containing a single dart file named
 /// `<name>.dart` that contains a line of Dart code.
@@ -465,8 +474,20 @@
 
 /// Defines an integration test. The [body] should schedule a series of
 /// operations which will be run asynchronously.
-void integration(String description, void body()) {
-  test(description, () {
+void integration(String description, void body()) =>
+  _integration(description, body, test);
+
+/// Like [integration], but causes only this test to run.
+void solo_integration(String description, void body()) =>
+  _integration(description, body, solo_test);
+
+void _integration(String description, void body(), [Function testFn]) {
+  testFn(description, () {
+    // Ensure the SDK version is always available.
+    dir(sdkPath, [
+      file('version', '0.1.2.3')
+    ]).scheduleCreate();
+
     // Schedule the test.
     body();
 
@@ -590,14 +611,15 @@
 /// [Future] may have a type other than [Process].
 Future _doPub(Function fn, sandboxDir, List args, Future<Uri> tokenEndpoint) {
   String pathInSandbox(path) => join(getFullPath(sandboxDir), path);
-
-  return Future.wait([
-    ensureDir(pathInSandbox(appPath)),
-    _awaitObject(args),
-    tokenEndpoint == null ? new Future.immediate(null) : tokenEndpoint
-  ]).then((results) {
-    var args = results[1];
-    var tokenEndpoint = results[2];
+  return defer(() {
+    ensureDir(pathInSandbox(appPath));
+    return Future.wait([
+      _awaitObject(args),
+      tokenEndpoint == null ? new Future.immediate(null) : tokenEndpoint
+    ]);
+  }).then((results) {
+    var args = results[0];
+    var tokenEndpoint = results[1];
     // Find a Dart executable we can use to spawn. Use the same one that was
     // used to run this script itself.
     var dartBin = new Options().executable;
@@ -782,7 +804,7 @@
 
   /// Loads the file at [path] from within this descriptor. If [path] is empty,
   /// loads the contents of the descriptor itself.
-  InputStream load(List<String> path);
+  ByteStream load(List<String> path);
 
   /// Schedules the directory to be created before Pub is run with
   /// [schedulePub]. The directory will be created relative to the sandbox
@@ -805,15 +827,15 @@
   }
 
   /// Validates that at least one file in [dir] matching [name] is valid
-  /// according to [validate]. [validate] should complete to an exception if
-  /// the input path is invalid.
+  /// 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)) {
     // Special-case strings to support multi-level names like "myapp/packages".
     if (name is String) {
       var path = join(dir, name);
-      return exists(path).then((exists) {
-        if (!exists) {
-          throw new ExpectException('File $name in $dir not found.');
+      return defer(() {
+        if (!entryExists(path)) {
+          throw new ExpectException('Entry $path not found.');
         }
         return validate(path);
       });
@@ -883,39 +905,34 @@
 
   /// Creates the file within [dir]. Returns a [Future] that is completed after
   /// the creation is done.
-  Future<File> create(dir) => new Future.immediate(null).then((_) =>
-      writeBinaryFile(join(dir, _stringName), contents));
+  Future<File> create(dir) =>
+      defer(() => writeBinaryFile(join(dir, _stringName), contents));
 
   /// Deletes the file within [dir]. Returns a [Future] that is completed after
   /// the deletion is done.
-  Future delete(dir) {
-    return deleteFile(join(dir, _stringName));
-  }
+  Future delete(dir) =>
+      defer(() => deleteFile(join(dir, _stringName)));
 
   /// Validates that this file correctly matches the actual file at [path].
   Future validate(String path) {
     return _validateOneMatch(path, (file) {
-      return readTextFile(file).then((text) {
-        if (text == textContents) return null;
+      var text = readTextFile(file);
+      if (text == textContents) return null;
 
-        throw new ExpectException(
-            'File $file should contain:\n\n$textContents\n\n'
-            'but contained:\n\n$text');
-      });
+      throw new ExpectException(
+          'File $file should contain:\n\n$textContents\n\n'
+          'but contained:\n\n$text');
     });
   }
 
   /// Loads the contents of the file.
-  InputStream load(List<String> path) {
+  ByteStream load(List<String> path) {
     if (!path.isEmpty) {
       var joinedPath = Strings.join(path, '/');
       throw "Can't load $joinedPath from within $name: not a directory.";
     }
 
-    var stream = new ListInputStream();
-    stream.write(contents);
-    stream.markEndOfStream();
-    return stream;
+    return new ByteStream.fromBytes(contents);
   }
 }
 
@@ -933,13 +950,13 @@
   /// Creates the file within [dir]. Returns a [Future] that is completed after
   /// the creation is done.
   Future<Directory> create(parentDir) {
-    // Create the directory.
-    return ensureDir(join(parentDir, _stringName)).then((dir) {
-      if (contents == null) return new Future<Directory>.immediate(dir);
+    return defer(() {
+      // Create the directory.
+      var dir = ensureDir(join(parentDir, _stringName));
+      if (contents == null) return dir;
 
       // Recursively create all of its children.
-      final childFutures =
-          contents.map((child) => child.create(dir)).toList();
+      var childFutures = contents.map((child) => child.create(dir)).toList();
       // Only complete once all of the children have been created too.
       return Future.wait(childFutures).then((_) => dir);
     });
@@ -967,7 +984,7 @@
   }
 
   /// Loads [path] from within this directory.
-  InputStream load(List<String> path) {
+  ByteStream load(List<String> path) {
     if (path.isEmpty) {
       throw "Can't load the contents of $name: is a directory.";
     }
@@ -997,10 +1014,10 @@
 
   Future delete(dir) => _future.then((desc) => desc.delete(dir));
 
-  InputStream load(List<String> path) {
-    var resultStream = new ListInputStream();
-    _future.then((desc) => pipeInputToInput(desc.load(path), resultStream));
-    return resultStream;
+  ByteStream load(List<String> path) {
+    var controller = new StreamController<List<int>>();
+    _future.then((desc) => store(desc.load(path), controller));
+    return new ByteStream(controller.stream);
   }
 }
 
@@ -1093,7 +1110,7 @@
       tempDir = _tempDir;
       return Future.wait(contents.map((child) => child.create(tempDir)));
     }).then((createdContents) {
-      return consumeInputStream(createTarGz(createdContents, baseDir: tempDir));
+      return createTarGz(createdContents, baseDir: tempDir).toBytes();
     }).then((bytes) {
       return new File(join(parentDir, _stringName)).writeAsBytes(bytes);
     }).then((file) {
@@ -1112,13 +1129,13 @@
   }
 
   /// Loads the contents of this tar file.
-  InputStream load(List<String> path) {
+  ByteStream load(List<String> path) {
     if (!path.isEmpty) {
       var joinedPath = Strings.join(path, '/');
       throw "Can't load $joinedPath from within $name: not a directory.";
     }
 
-    var sinkStream = new ListInputStream();
+    var controller = new StreamController<List<int>>();
     var tempDir;
     // TODO(rnystrom): Use withTempDir() here.
     // TODO(nweiz): propagate any errors to the return value. See issue 3657.
@@ -1127,11 +1144,11 @@
       return create(tempDir);
     }).then((tar) {
       var sourceStream = tar.openInputStream();
-      return pipeInputToInput(sourceStream, sinkStream).then((_) {
+      return store(wrapInputStream(sourceStream), controller).then((_) {
         tempDir.delete(recursive: true);
       });
     });
-    return sinkStream;
+    return new ByteStream(controller.stream);
   }
 }
 
@@ -1143,14 +1160,14 @@
   Future delete(dir) => new Future.immediate(null);
 
   Future validate(String dir) {
-    return exists(join(dir, name)).then((exists) {
-      if (exists) {
+    return defer(() {
+      if (entryExists(join(dir, name))) {
         throw new ExpectException('File $name in $dir should not exist.');
       }
     });
   }
 
-  InputStream load(List<String> path) {
+  ByteStream load(List<String> path) {
     if (path.isEmpty) {
       throw "Can't load the contents of $name: it doesn't exist.";
     } else {
@@ -1168,12 +1185,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(join(sandboxDir, cachePath));
 
-    return Entrypoint.load(join(sandboxDir, appPath), cache)
-        .then((entrypoint) {
-      var validator = fn(entrypoint);
+    return defer(() {
+      var validator = fn(new Entrypoint(join(sandboxDir, appPath), cache));
       return validator.validate().then((_) {
         return new Pair(validator.errors, validator.warnings);
       });
@@ -1220,21 +1235,43 @@
   final String name;
 
   /// The process future that's scheduled to run.
-  Future<Process> _processFuture;
+  Future<PubProcess> _processFuture;
 
   /// The process that's scheduled to run. It may be null.
-  Process _process;
+  PubProcess _process;
 
   /// The exit code of the scheduled program. It may be null.
   int _exitCode;
 
-  /// A [StringInputStream] wrapping the stdout of the process that's scheduled
-  /// to run.
-  final Future<StringInputStream> _stdoutFuture;
+  /// A future that will complete to a list of all the lines emitted on the
+  /// process's standard output stream. This is independent of what data is read
+  /// from [_stdout].
+  Future<List<String>> _stdoutLines;
 
-  /// A [StringInputStream] wrapping the stderr of the process that's scheduled
-  /// to run.
-  final Future<StringInputStream> _stderrFuture;
+  /// A [Stream] of stdout lines emitted by the process that's scheduled to run.
+  /// It may be null.
+  Stream<String> _stdout;
+
+  /// A [Future] that will resolve to [_stdout] once it's available.
+  Future get _stdoutFuture => _processFuture.then((_) => _stdout);
+
+  /// A [StreamSubscription] that controls [_stdout].
+  StreamSubscription _stdoutSubscription;
+
+  /// A future that will complete to a list of all the lines emitted on the
+  /// process's standard error stream. This is independent of what data is read
+  /// from [_stderr].
+  Future<List<String>> _stderrLines;
+
+  /// A [Stream] of stderr lines emitted by the process that's scheduled to run.
+  /// It may be null.
+  Stream<String> _stderr;
+
+  /// A [Future] that will resolve to [_stderr] once it's available.
+  Future get _stderrFuture => _processFuture.then((_) => _stderr);
+
+  /// A [StreamSubscription] that controls [_stderr].
+  StreamSubscription _stderrSubscription;
 
   /// The exit code of the process that's scheduled to run. This will naturally
   /// only complete once the process has terminated.
@@ -1251,43 +1288,61 @@
   bool _endExpected = false;
 
   /// Wraps a [Process] [Future] in a scheduled process.
-  ScheduledProcess(this.name, Future<Process> process)
-    : _processFuture = process,
-      _stdoutFuture = process.then((p) => new StringInputStream(p.stdout)),
-      _stderrFuture = process.then((p) => new StringInputStream(p.stderr)) {
-    process.then((p) {
+  ScheduledProcess(this.name, Future<PubProcess> process)
+    : _processFuture = process {
+    var pairFuture = process.then((p) {
       _process = p;
+
+      byteStreamToLines(stream) {
+        var handledErrors = wrapStream(stream.handleError((e) {
+          registerException(e.error, e.stackTrace);
+        }));
+        return streamToLines(new ByteStream(handledErrors).toStringStream());
+      }
+
+      var stdoutTee = tee(byteStreamToLines(p.stdout));
+      var stdoutPair = streamWithSubscription(stdoutTee.last);
+      _stdout = stdoutPair.first;
+      _stdoutSubscription = stdoutPair.last;
+
+      var stderrTee = tee(byteStreamToLines(p.stderr));
+      var stderrPair = streamWithSubscription(stderrTee.last);
+      _stderr = stderrPair.first;
+      _stderrSubscription = stderrPair.last;
+
+      return new Pair(stdoutTee.first, stderrTee.first);
     });
 
+    _stdoutLines = pairFuture.then((pair) => pair.first.toList());
+    _stderrLines = pairFuture.then((pair) => pair.last.toList());
+
     _schedule((_) {
       if (!_endScheduled) {
         throw new StateError("Scheduled process $name must have shouldExit() "
             "or kill() called before the test is run.");
       }
 
-      return process.then((p) {
-        p.onExit = (c) {
+      process.then((p) => p.exitCode).then((exitCode) {
+        if (_endExpected) {
+          _exitCode = exitCode;
+          _exitCodeCompleter.complete(exitCode);
+          return;
+        }
+
+        // Sleep for half a second in case _endExpected is set in the next
+        // scheduled event.
+        return sleep(500).then((_) {
           if (_endExpected) {
-            _exitCode = c;
-            _exitCodeCompleter.complete(c);
+            _exitCodeCompleter.complete(exitCode);
             return;
           }
 
-          // Sleep for half a second in case _endExpected is set in the next
-          // scheduled event.
-          sleep(500).then((_) {
-            if (_endExpected) {
-              _exitCodeCompleter.complete(c);
-              return;
-            }
-
-            _printStreams().then((_) {
-              registerException(new ExpectException("Process $name ended "
-                  "earlier than scheduled with exit code $c"));
-            });
-          });
-        };
-      });
+          return _printStreams();
+        }).then((_) {
+          registerException(new ExpectException("Process $name ended "
+              "earlier than scheduled with exit code $exitCode"));
+        });
+      }).catchError((e) => registerException(e.error, e.stackTrace));
     });
 
     _scheduleOnException((_) {
@@ -1306,15 +1361,15 @@
       if (_process == null) return;
       // Ensure that the process is dead and we aren't waiting on any IO.
       _process.kill();
-      _process.stdout.close();
-      _process.stderr.close();
+      _stdoutSubscription.cancel();
+      _stderrSubscription.cancel();
     });
   }
 
   /// Reads the next line of stdout from the process.
   Future<String> nextLine() {
     return _scheduleValue((_) {
-      return timeout(_stdoutFuture.then((stream) => readLine(stream)),
+      return timeout(_stdoutFuture.then((stream) => streamFirst(stream)),
           _SCHEDULE_TIMEOUT,
           "waiting for the next stdout line from process $name");
     });
@@ -1323,7 +1378,7 @@
   /// Reads the next line of stderr from the process.
   Future<String> nextErrLine() {
     return _scheduleValue((_) {
-      return timeout(_stderrFuture.then((stream) => readLine(stream)),
+      return timeout(_stderrFuture.then((stream) => streamFirst(stream)),
           _SCHEDULE_TIMEOUT,
           "waiting for the next stderr line from process $name");
     });
@@ -1338,7 +1393,8 @@
     }
 
     return _scheduleValue((_) {
-      return timeout(_stdoutFuture.then(consumeStringInputStream),
+      return timeout(_stdoutFuture.then((stream) => stream.toList())
+              .then((lines) => lines.join("\n")),
           _SCHEDULE_TIMEOUT,
           "waiting for the last stdout line from process $name");
     });
@@ -1353,7 +1409,8 @@
     }
 
     return _scheduleValue((_) {
-      return timeout(_stderrFuture.then(consumeStringInputStream),
+      return timeout(_stderrFuture.then((stream) => stream.toList())
+              .then((lines) => lines.join("\n")),
           _SCHEDULE_TIMEOUT,
           "waiting for the last stderr line from process $name");
     });
@@ -1362,7 +1419,7 @@
   /// Writes [line] to the process as stdin.
   void writeLine(String line) {
     _schedule((_) => _processFuture.then(
-        (p) => p.stdin.writeString('$line\n')));
+        (p) => p.stdin.add('$line\n'.charCodes)));
   }
 
   /// Kills the process, and waits until it's dead.
@@ -1371,7 +1428,7 @@
     _schedule((_) {
       _endExpected = true;
       _process.kill();
-      timeout(_exitCodeCompleter.future, _SCHEDULE_TIMEOUT,
+      timeout(_exitCodeFuture, _SCHEDULE_TIMEOUT,
           "waiting for process $name to die");
     });
   }
@@ -1382,7 +1439,7 @@
     _endScheduled = true;
     _schedule((_) {
       _endExpected = true;
-      return timeout(_exitCodeCompleter.future, _SCHEDULE_TIMEOUT,
+      return timeout(_exitCodeFuture, _SCHEDULE_TIMEOUT,
           "waiting for process $name to exit").then((exitCode) {
         if (expectedExitCode != null) {
           expect(exitCode, equals(expectedExitCode));
@@ -1392,24 +1449,21 @@
   }
 
   /// Prints the remaining data in the process's stdout and stderr streams.
-  /// Prints nothing if the straems are empty.
+  /// Prints nothing if the streams are empty.
   Future _printStreams() {
-    Future printStream(String streamName, StringInputStream stream) {
-      return consumeStringInputStream(stream).then((output) {
-        if (output.isEmpty) return;
+    void printStream(String streamName, List<String> lines) {
+      if (lines.isEmpty) return;
 
-        print('\nProcess $name $streamName:');
-        for (var line in output.trim().split("\n")) {
-          print('| $line');
-        }
-        return;
-      });
+      print('\nProcess $name $streamName:');
+      for (var line in lines) {
+        print('| $line');
+      }
     }
 
-    return _stdoutFuture.then((stdout) {
-      return _stderrFuture.then((stderr) {
-        return printStream('stdout', stdout)
-            .then((_) => printStream('stderr', stderr));
+    return _stdoutLines.then((stdoutLines) {
+      printStream('stdout', stdoutLines);
+      return _stderrLines.then((stderrLines) {
+        printStream('stderr', stderrLines);
       });
     });
   }
@@ -1482,7 +1536,7 @@
   /// Raises an error complaining of an unexpected request.
   void _awaitHandle(HttpRequest request, HttpResponse response) {
     if (_ignored.contains(new Pair(request.method, request.path))) return;
-    var future = timeout(new Future.immediate(null).then((_) {
+    var future = timeout(defer(() {
       if (_handlers.isEmpty) {
         fail('Unexpected ${request.method} request to ${request.path}.');
       }
diff --git a/utils/tests/pub/update/git/do_not_update_if_unneeded_test.dart b/utils/tests/pub/update/git/do_not_update_if_unneeded_test.dart
index 15fa3f9..3f0f909 100644
--- a/utils/tests/pub/update/git/do_not_update_if_unneeded_test.dart
+++ b/utils/tests/pub/update/git/do_not_update_if_unneeded_test.dart
@@ -15,7 +15,7 @@
 
     git('foo.git', [
       libDir('foo'),
-      libPubspec("foo", "1.0.0", [{"git": "../foo-dep.git"}])
+      libPubspec("foo", "1.0.0", deps: [{"git": "../foo-dep.git"}])
     ]).scheduleCreate();
 
     git('foo-dep.git', [
@@ -39,7 +39,7 @@
 
     git('foo.git', [
       libDir('foo', 'foo 2'),
-      libPubspec("foo", "1.0.0", [{"git": "../foo-dep.git"}])
+      libPubspec("foo", "1.0.0", deps: [{"git": "../foo-dep.git"}])
     ]).scheduleCreate();
 
     git('foo-dep.git', [
diff --git a/utils/tests/pub/update/pub_update_test.dart b/utils/tests/pub/update/pub_update_test.dart
index dee0074..c28951c 100644
--- a/utils/tests/pub/update/pub_update_test.dart
+++ b/utils/tests/pub/update/pub_update_test.dart
@@ -69,7 +69,6 @@
       'directory', () {
     // Using an SDK source, but this should be true of all sources.
     dir(sdkPath, [
-      file('version', '0.1.2.3'),
       dir('pkg', [
         dir('foo', [
           libPubspec('foo', '0.0.0-not.used')
diff --git a/utils/tests/pub/validator_test.dart b/utils/tests/pub/validator_test.dart
index b9eb6b7..b11d90f 100644
--- a/utils/tests/pub/validator_test.dart
+++ b/utils/tests/pub/validator_test.dart
@@ -127,7 +127,7 @@
 
     integration('has an unconstrained dependency on "unittest"', () {
       dir(appPath, [
-        libPubspec("test_pkg", "1.0.0", [
+        libPubspec("test_pkg", "1.0.0", deps: [
           {'hosted': 'unittest'}
         ])
       ]).scheduleCreate();
@@ -342,7 +342,7 @@
           }));
 
           dir(appPath, [
-            libPubspec("test_pkg", "1.0.0", [
+            libPubspec("test_pkg", "1.0.0", deps: [
               {'git': 'git://github.com/dart-lang/foo'}
             ])
           ]).scheduleCreate();
@@ -366,7 +366,7 @@
           }));
 
           dir(appPath, [
-            libPubspec("test_pkg", "1.0.0", [
+            libPubspec("test_pkg", "1.0.0", deps: [
               {'git': 'git://github.com/dart-lang/foo'}
             ])
           ]).scheduleCreate();
@@ -390,7 +390,7 @@
           }));
 
           dir(appPath, [
-            libPubspec("test_pkg", "1.0.0", [
+            libPubspec("test_pkg", "1.0.0", deps: [
               {'git': 'git://github.com/dart-lang/foo'}
             ])
           ]).scheduleCreate();
@@ -411,7 +411,7 @@
           }));
 
           dir(appPath, [
-            libPubspec("test_pkg", "1.0.0", [
+            libPubspec("test_pkg", "1.0.0", deps: [
               {
                 'git': {'url': 'git://github.com/dart-lang/foo'},
                 'version': '>=1.0.0 <2.0.0'
@@ -434,7 +434,7 @@
           }));
 
           dir(appPath, [
-            libPubspec("test_pkg", "1.0.0", [
+            libPubspec("test_pkg", "1.0.0", deps: [
               {
                 'git': {'url': 'git://github.com/dart-lang/foo'},
                 'version': '0.2.3'
@@ -452,7 +452,7 @@
       group('and it should not suggest a version', () {
         integration("if there's no lockfile", () {
           dir(appPath, [
-            libPubspec("test_pkg", "1.0.0", [
+            libPubspec("test_pkg", "1.0.0", deps: [
               {'hosted': 'foo'}
             ])
           ]).scheduleCreate();
@@ -464,7 +464,7 @@
         integration("if the lockfile doesn't have an entry for the "
             "dependency", () {
           dir(appPath, [
-            libPubspec("test_pkg", "1.0.0", [
+            libPubspec("test_pkg", "1.0.0", deps: [
               {'hosted': 'foo'}
             ]),
             file("pubspec.lock", json.stringify({
@@ -490,7 +490,7 @@
         integration('and it should suggest a constraint based on the locked '
             'version', () {
           dir(appPath, [
-            libPubspec("test_pkg", "1.0.0", [
+            libPubspec("test_pkg", "1.0.0", deps: [
               {'hosted': 'foo'}
             ]),
             file("pubspec.lock", json.stringify({
@@ -515,7 +515,7 @@
         integration('and it should suggest a concrete constraint if the locked '
             'version is pre-1.0.0', () {
           dir(appPath, [
-            libPubspec("test_pkg", "1.0.0", [
+            libPubspec("test_pkg", "1.0.0", deps: [
               {'hosted': 'foo'}
             ]),
             file("pubspec.lock", json.stringify({
@@ -541,7 +541,7 @@
 
     integration('has a hosted dependency on itself', () {
       dir(appPath, [
-        libPubspec("test_pkg", "1.0.0", [
+        libPubspec("test_pkg", "1.0.0", deps: [
           {'hosted': {'name': 'test_pkg', 'version': '>=1.0.0'}}
         ])
       ]).scheduleCreate();