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();
